2014-05-13 35 views
4

我一直在努力理解解包如何工作。更具体地说,文档中的这个特定示例最令我困惑,因为当我输入它完全相同时,它不会给我相同的输出。 https://docs.python.org/2/library/struct.html#struct-examplesPython中的结构和解包

>>> from struct import * 
>>> pack('hhl', 1, 2, 3) 
'\x00\x01\x00\x02\x00\x00\x00\x03' 
>>> unpack('hhl', '\x00\x01\x00\x02\x00\x00\x00\x03') 
(1, 2, 3) 
>>> calcsize('hhl') 
8 

8字节大小有意义但是当我做calcsize(“HHL”)它返回16.贮藏包(“HHL”,1,2,3)作为变量和拆包它工作正常,但使用十六进制值没有。我收到错误“解压缩需要一个长度为16的字符串参数”,任何想法是什么问题?由于

+1

该文档指出,该示例是在一个big-endian机器上完成的。请注意,大多数(?)流行处理器使用little-endian字节排序,所以输出字符串可能会不同。只要你打开包装生成的字符串,你就会好起来的。你也可以强制一个特定的字节顺序(见文档)。 – jedwards

+0

是的这是原来的问题。格式化为big-endian给出了我期待的结果 –

回答

2

这是因为当你做unhexlify它:

>>> pack('hhl', 1, 2, 3) 
'\x00\x01\x00\x02\x00\x00\x00\x03' 

它没有返回字符串与[\,x,0, 0,...]但是包含以十六进制给出的每个数字的字节阵列:

>>> pack('hhl', 1, 2, 3)[0] 
'\x00' 

所以,当你做:

>>> unpack('hhl', '\x00\x01\x00\x02\x00\x00\x00\x03') 

你实际上是试图解开一个字符串,就像我以前说。而如果你这样做:

>>> s = pack('hhl', 1, 2, 3) 
'\x00\x01\x00\x02\x00\x00\x00\x03' 
>>> unpack('hhl', s) 
(1, 2, 3) 

它按预期工作。

现在,正如@falstru所说的,一种将十六进制字符串转换为结构可以理解的字节数组的方法是使用binascii.unhexlify,它处理字节顺序和转换。你也可以自己做:

>>> unpack('hhl', str(bytearray([1,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0]))) 
(1, 2, 3) 
1

如果你指的是十六进制字符串像'0001000200000003',你需要首先使用binascii.unhexlify(或binascii.a2b_hex

>>> import struct 
>>> import binascii 
>>> struct.unpack('>hhl', binascii.unhexlify('0001000200000003')) 
(1, 2, 3)