2014-05-13 40 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)