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