Struct.error: 's' 的参数必须是字节对象,已提供

Smo*_*ick 3 python struct exception python-3.x

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

import struct

string = "blab"

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

print(packed_data)
Run Code Online (Sandbox Code Playgroud)

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

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

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

tde*_*ney 7

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

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

但即使这样也是有问题的。假设你的字符串不在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'))
    ??
    >>> 
Run Code Online (Sandbox Code Playgroud)

如果您确实需要限制为 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)
Run Code Online (Sandbox Code Playgroud)