【问题标题】:python encode() and decode() issuespython encode() 和 decode() 问题
【发布时间】:2022-01-06 22:21:49
【问题描述】:

谁能帮我解决这个问题 编码方法不起作用,我找不到原因

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

【问题讨论】:

  • 请向我们展示整个错误。
  • 我刚刚编辑了问题:)
  • 你能分享一下这个函数的调用实际上导致了错误吗?此外,您发布的代码似乎已在,ret 处缩短,因为没有右括号。最后,encode_finish 是什么?
  • 你能包含完整的堆栈跟踪吗?
  • 请注意,struct.pack() 通常会返回 bytesbytes 没有 .encode() 方法,只有 .decode() 一个 - 您是否尝试先解码然后重新-编码为"hex"?

标签: python python-3.x decode encode


【解决方案1】:

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

如果是这样,您需要导入 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)

鉴于原始代码的链接,这取决于 encodeAVPAVP_Value 的预期类型 - 在共享代码中从未调用它,也没有记录其类型,也没有提供类型提示,所以这是不可能的说。

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

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

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

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

【讨论】:

  • 这越来越接近但仍然不正确 - 错误消息是因为 data 不是 bytes - 它没有通过 pack(...) 调用
  • @AnthonySottile encode_OctetString 只能在 databytes 对象的情况下调用 - 如果不是,那么呈现的代码没有问题,但代码调用它。除非该函数旨在处理 data 作为字符串。
  • 我已经更新了答案以提供替代方案 - 在任何一种情况下,codecs.encode 都将允许 "hex" 编码。
  • 解决了!非常感谢
  • 不客气 - 请随意勾选已接受的答案,以表明问题已得到解答,或者如果缺少某些内容,请发布您自己的答案。
猜你喜欢
  • 2013-10-29
  • 2016-03-02
  • 2015-03-27
  • 2011-06-28
  • 2016-04-17
  • 1970-01-01
  • 1970-01-01
  • 2016-02-24
  • 1970-01-01
相关资源
最近更新 更多