[Python開發]細究Python struct 模組
struct — Interpret bytes as packed binary data,將位元組與二進位制檔案相互轉化的工具Python struct 模組。更多見:iii.run
關於格式字串
在Python手冊中,給出了C語言中常用型別與Python型別對應的格式符:
格式符 | C語言型別 | 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的值根據格式符,轉換為字串,準確來說是Byte。這個地方我們之前有提過,Python3內的unicode和bytes,在Py3內文字總是Unicode,由str型別表示,二進位制資料則由bytes型別表示。
Py2是沒有Byte這麼個東西的。引數fmt是格式字串,v1, v2, ...表示要轉換的python值。下面的例子將兩個整數轉換為字串:
import struct
a = 20
b = 400
byte = struct.pack("ii", a, b) #轉換後的str相當於其他語言中的位元組流(位元組陣列),可以在網路上傳輸
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"表示轉換為int,'ii'表示有兩個int變數。進行轉換後的結果長度為8個位元組(int型別佔用4個位元組,兩個int為8個位元組)可以看到輸出的結果是亂碼,因為結果是二進位制資料,所以顯示為亂碼。可以使用python的內建函式repr來獲取可識別的字串 ,以上問題在Python3中不會出現了其中十六進位制的0x00000014, 0x00000190分別表示20和400。
上一段程式碼最後那個很有意思誒,竟然是預設採用小端。
大端儲存和小端儲存
小端:較高的有效位元組存放在較高的儲存器地址,較低的有效位元組存放在較低的儲存器地址。
大端:較高的有效位元組存放在較低的儲存器地址,較低的有效位元組存放在較高的儲存器地址。
如果將一個16位的整數0x1234存放到一個短整型變數(short)中。這個短整型變數在記憶體中的儲存在大小端模式由下表所示。
地址偏移 | 大端模式 | 小端模式 |
---|---|---|
0x00 | 12(OP0) | 34(OP1) |
0x01 | 34(OP1) | 12(OP0) |
採用大端方式進行資料存放符合人類的正常思維,而採用小端方式進行資料存放利於計算機處理。
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相反,用於將位元組流轉換成python資料型別。它的函式原型為:struct.unpack(fmt, string),該函式返回一個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用於計算格式字串所對應的結果的長度,如:struct.calcsize('ii'),返回8。因為兩個int型別所佔用的長度是8個位元組。
參考連結:
https://docs.python.org/3/library/struct.html
http://blog.csdn.net/occupy8/article/details/11052103
作者:mmmwhy
連結:https://www.jianshu.com/p/d7f3ec47dd36
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。