細(xì)究Python struct 模塊

struct — Interpret bytes as packed binary data,將字節(jié)與二進(jìn)制文件相互轉(zhuǎn)化的工具Python struct 模塊。更多見:iii.run


關(guān)于格式字符串

在Python手冊(cè)中,給出了C語(yǔ)言中常用類型與Python類型對(duì)應(yīng)的格式符:

格式符 C語(yǔ)言類型 Python類型
x pad byte no value
c char string of length 1
b signed char integer
B unsigned char integer
? _Bool bool
h short integer
H unsigned short integer
i int integer
I unsigned int integer or long
l long integer
L unsigned long long
q long long long
Q unsigned long long long
f float float
d double float
s char[] string
p char[] string
P void *

struct.pack(fmt, v1, v2, ...)

Return a string containing the values v1, v2, ... packed according to the given format. The arguments must match the values required by the format exactly.

struct.pack用于將Python的值根據(jù)格式符,轉(zhuǎn)換為字符串,準(zhǔn)確來說是Byte。這個(gè)地方我們之前有提過,Python3內(nèi)的unicode和bytes,在Py3內(nèi)文本總是Unicode,由str類型表示,二進(jìn)制數(shù)據(jù)則由bytes類型表示。


Py2是沒有Byte這么個(gè)東西的。參數(shù)fmt是格式字符串,v1, v2, ...表示要轉(zhuǎn)換的python值。下面的例子將兩個(gè)整數(shù)轉(zhuǎn)換為字符串:

import struct  

a = 20  
b = 400

byte = struct.pack("ii", a, b) #轉(zhuǎn)換后的str相當(dāng)于其他語(yǔ)言中的字節(jié)流(字節(jié)數(shù)組),可以在網(wǎng)絡(luò)上傳輸  
big = struct.pack(">ii", a, b)  #大端保存
small = struct.pack("<ii", a, b) #小端保存
print(byte)
# >>>:b'\x14\x00\x00\x00\x90\x01\x00\x00'
print(big)
# >>>:b'\x00\x00\x00\x14\x00\x00\x01\x90'
print(small)
# >>>:b'\x14\x00\x00\x00\x90\x01\x00\x00'
print (byte[0],byte[4]) 
# >>>:b'\x14\x00\x00\x00\x90\x01\x00\x00'

格式符"i"表示轉(zhuǎn)換為int,'ii'表示有兩個(gè)int變量。進(jìn)行轉(zhuǎn)換后的結(jié)果長(zhǎng)度為8個(gè)字節(jié)(int類型占用4個(gè)字節(jié),兩個(gè)int為8個(gè)字節(jié))可以看到輸出的結(jié)果是亂碼,因?yàn)榻Y(jié)果是二進(jìn)制數(shù)據(jù),所以顯示為亂碼??梢允褂胮ython的內(nèi)置函數(shù)repr來獲取可識(shí)別的字符串 ,以上問題在Python3中不會(huì)出現(xiàn)了其中十六進(jìn)制的0x00000014, 0x00000190分別表示20和400。

上一段代碼最后那個(gè)很有意思誒,竟然是默認(rèn)采用小端。

大端存儲(chǔ)和小端存儲(chǔ)

小端:較高的有效字節(jié)存放在較高的存儲(chǔ)器地址,較低的有效字節(jié)存放在較低的存儲(chǔ)器地址。
大端:較高的有效字節(jié)存放在較低的存儲(chǔ)器地址,較低的有效字節(jié)存放在較高的存儲(chǔ)器地址。

如果將一個(gè)16位的整數(shù)0x1234存放到一個(gè)短整型變量(short)中。這個(gè)短整型變量在內(nèi)存中的存儲(chǔ)在大小端模式由下表所示。

地址偏移 大端模式 小端模式
0x00 12(OP0) 34(OP1)
0x01 34(OP1) 12(OP0)

采用大端方式進(jìn)行數(shù)據(jù)存放符合人類的正常思維,而采用小端方式進(jìn)行數(shù)據(jù)存放利于計(jì)算機(jī)處理。

struct.unpack(fmt, buffer)

Unpack from the buffer buffer (presumably packed by pack(fmt, ...)) according to the format string fmt. The result is a tuple even if it contains exactly one item. The buffer’s size in bytes must match the size required by the format, as reflected by calcsize().

struct.unpack做的工作剛好與struct.pack相反,用于將字節(jié)流轉(zhuǎn)換成python數(shù)據(jù)類型。它的函數(shù)原型為:struct.unpack(fmt, string),該函數(shù)返回一個(gè)tuple。

a1, a2 = struct.unpack("ii", byte)  
print(type(struct.unpack("ii", byte)),a1,a2)
# >>>:<class 'tuple'> 20 400

struct.calcsize(fmt)

Return the size of the struct (and hence of the bytes object produced by pack(fmt, ...)) corresponding to the format string fmt.

struct.calcsize用于計(jì)算格式字符串所對(duì)應(yīng)的結(jié)果的長(zhǎng)度,如:struct.calcsize('ii'),返回8。因?yàn)閮蓚€(gè)int類型所占用的長(zhǎng)度是8個(gè)字節(jié)。


參考鏈接:
https://docs.python.org/3/library/struct.html
http://blog.csdn.net/occupy8/article/details/11052103

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容