【问题标题】:Struct.error: argument for 's' must be a bytes object, already suppliedStruct.error:“s”的参数必须是字节对象,已提供
【发布时间】:2016-01-19 18:22:32
【问题描述】:

我一直在用 Python 编写 TCP/IP 连接程序,并且遇到了使用 Struct 的需求。所以我导入了模块,一段时间后遇到了一个非常特殊的问题。当我运行下面的代码时,我得到了标题中指定的错误,在我检查了一些其他答案和文档后应该可以工作。

import struct

string = "blab"

s = struct.Struct(b'4s')
packed_data = s.pack(string)

print(packed_data)

据我发现,应该通过在 s 变量中使用的字符串前面加上“b”或使用解析“utf-8”作为编码参数的bytes() 函数来解决此问题。两个都试了,同样的错误。

我不知道可能出了什么问题,所以我错过了什么吗?我在网上找不到关于这个问题的相关信息,所以这就是我现在在这里发帖的原因。

任何帮助表示赞赏并提前感谢!

【问题讨论】:

  • 试试str = b"blab"(注意变量名string,有一个核心模块叫string

标签: python python-3.x exception struct


【解决方案1】:

一个问题是你把“b”放在了错误的地方。你把它放在格式字符串中,当要打包的数据需要是字节字符串时。

    >>> string = "blab"
    >>> s = struct.Struct('4s')
    >>> packed_data = s.pack(string.encode('utf-8'))
    >>> print(packed_data)
    b'blab'

但即使这样也是有问题的。假设您的字符串不在ascii 字符集中...假设它是希腊语,那么 UTF8 编码的字符串超过 4 个字节并且您写入了一个截断值

    >>> string = "ΑΒΓΔ"
    >>> s = struct.Struct('4s')
    >>> 
    >>> packed_data = s.pack(string.encode('utf-8'))
    >>> print('utf8len', len(string.encode('utf-8')), 'packedlen', len(packed_data))
    utf8len 8 packedlen 4
    >>> print(packed_data)
    b'\xce\x91\xce\x92'
    >>> print(struct.unpack('4s', packed_data)[0].decode('utf-8'))
    ΑΒ
    >>> 

如果您确实需要限制为 4 个字节,请使用 ascii 而不是 utf-8 转换原始字符串,这样任何不可编码的 unicode 字符都会立即引发异常。

    >>> string = "ΑΒΓΔ"
    >>> s = struct.Struct('4s')
    >>> 
    >>> packed_data = s.pack(string.encode('ascii'))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

【讨论】:

  • 哦,我明白现在的情况了。主要问题来自于错误说's'的参数这误导我认为因为我有变量's'是 struct.Struct(...) 我认为这意味着 s 的参数(对于 struct .Struct(arg) 应该是一个字节对象,因此放错了位置。现在我仔细检查了一切,一切正常。感谢您的反馈和额外的信息!感谢 :)
【解决方案2】:
packed_data = s.pack(string.encode('utf-8'))

应该在 Py2 和 3 中都工作

来自 Python 2.7.11 的 Unicode HowTo:

另一个重要的方法是.encode([encoding], [errors='strict']), 它返回 Unicode 字符串的 8 位字符串版本,已编码 在请求的编码中。错误参数与 unicode() 构造函数的参数,还有一个 可能性;除了“严格”​​、“忽略”和“替换”,您还可以 还传递使用 XML 字符引用的“xmlcharrefreplace”。 以下示例显示了不同的结果:

https://docs.python.org/2/howto/unicode.html

【讨论】:

    猜你喜欢
    • 2018-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-16
    • 2017-02-15
    • 2013-04-18
    相关资源
    最近更新 更多