python3 struct.pack,以字符串作为参数

时间:2016-10-03 19:24:54

标签: string python-3.x struct.pack

我实际上想知道python3的struct.pack行为,但也许我错过了一些东西。

我通过UDP提交.jpg文件。顺便说一下:socket.sendTo()sendAll()函数抛出一个" Python IOError:[Errno 90]消息太长"当我尝试一次提交整个文件(~200kB)。所以我提交了1024字节的文件。没问题,我只是想知道为什么我在python文档中找到 nothing 关于这个大小限制的内容。

无论如何,我的主要问题是:我需要struct.pack在每篇文章的开头添加一些信息 - > 2个固定大小的字符串。

但是当我做的时候

chunk = struct.pack("!3c4cI", bytes("JPG", "utf-8"), bytes(dev_id, "utf-8"), i)

它去" struct.error:打包预期8件包装(得到3件)"

所以我得走了

chunk = struct.pack("!3c4ci", b"J", b"P", b"G", 
    bytes(dev_id[0:1], "utf-8"),
    bytes(dev_id[1:2], "utf-8"),
    bytes(dev_id[2:3], "utf-8"),
    bytes(dev_id[3:4], "utf-8"), i)

让它发挥作用。这是为什么!?

1 个答案:

答案 0 :(得分:2)

struct.pack要求每个项目作为单独的参数传递。此外,Python区分了charbyte,即使在C中它们是同义词,这就是为什么你需要为{bytes设置一个{1}}值的原因{1}},而不是0 ... 255范围内的整数。

但是,c也支持struct格式说明符,其中s代表给定长度的字符串:

s

或者,如果您至少使用Python 3.5 ,那么感谢PEP 448 -- Additional Unpacking Generalizations,您可以将>>> dev_id, i = 'R2D2', 42 >>> struct.pack("!3s4sI", b"JPG", dev_id.encode(), i) b'JPGR2D2\x00\x00\x00*' (无符号字节)格式与splat结合使用运算符B是这样的:

*

这里>>> struct.pack("!3B4BI", *b"JPG", *dev_id.encode(), i) 的作用是将给定*值中的每个字节解压缩为0 ... 255范围内的整数到单独的参数中;如果bytes导致4个UTF-8字节,则总共8个参数将传递给dev_id.encode()。与struct.pack不同,c接受单个字节值作为整数。

P.S。请注意,我直接使用B而不是调用b'JPG',并且默认情况下在bytes('JPG', 'UTF-8')编码的字符串上调用.encode(),以获得更短的代码。