python encode() 和 decode() 问题

python encode() and decode() issues

谁能帮我解决这个问题 编码方法无效,我无法发现原因

def encode_OctetString(A,flags,data):
    fs="!"+str(len(data))+"s"
    dbg="Encoding String format:",fs
    logging.debug(dbg)
    ret=struct.pack(fs,data).encode("hex")
    pktlen=8+len(ret)/2
    return encode_finish(A,flags,pktlen,ret

错误代码

 File "/home/ubuntu/diameter-test/libDiameter.py", line 434, in encode_OctetString
    ret=struct.pack(fs,data).encode("hex")
struct.error: argument for 's' must be a bytes object

请注意 struct.pack() 通常 return 一个 bytesbytes 没有 .encode() 方法,只有 .decode()一 - 您是否尝试先解码然后重新编码为 "hex"?

如果是这样,您需要导入 codecs.encode() 并将其应用于 bytes 对象:

import struct
import logging
import codecs


def encode_OctetString(A, flags, data):
    fs = "!" + str(len(data)) + "s"
    dbg = "Encoding String format:", fs
    logging.debug(dbg)
    ret = codecs.encode(struct.pack(fs, data), "hex")
    pktlen = 8 + len(ret) / 2
    return encode_finish(A, flags, pktlen, ret)

如果您以某种方式希望 encode_OctetString 处理字符串而不是 bytes 对象,您将使用:

def encode_OctetString(A, flags, data):
    fs = "!" + str(len(data)) + "s"
    dbg = "Encoding String format:", fs
    logging.debug(dbg)
    ret = codecs.encode(struct.pack(fs, data.encode()), "hex")
    pktlen = 8 + len(ret) / 2
    return encode_finish(A, flags, pktlen, ret)

给定原始代码的 link,这取决于 encodeAVPAVP_Value 的预期类型——它从未在共享代码中调用,也没有记录其类型并且没有提供类型提示,所以不可能说。

编辑(接受答案后):重要的是要注意字符串和 bytes 对象之间的区别。 Python让他们看起来很像,毕竟'hello'.encode()就变成了b'hello'吧?

但它们非常不同。字符串是一系列字符,没有您需要担心的特定编码。因此,'hello' 只是一个 'h',后跟一个 'e',等等 - 您不必担心存储中使用什么编码来表示这些字符。但是,b'hello' 是一系列具有特定编码的字节,如果使用以下命令将 解码为字符串,则 可以 解释为表示一系列字符 'hello'已知编码(默认为 UTF-8)。

这就是为什么在这个答案中,首先对 data 进行编码(使用 UTF-8,因为没有指定编码),以便 struct.pack 可以处理它(它需要字节,而不是一个字符串),然后使用“十六进制”编码将结果重新编码为十六进制字符串表示形式。这通常有点令人困惑,因为虽然它是一种编码,但结果是一个字符串。

要点应该是 bytes 只是字节,只有当你决定它们采用什么编码时才有意义。字符串 str 只是抽象的字符系列,编码无关紧要。编码意味着获取具有意义的内容并将其编码为表示该内容的二进制文件。解码意味着获取一堆二进制代码(字节)并将其解释回有意义的东西,比如字符串。