1. 程式人生 > >[Python開發]細究Python struct 模組

[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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。