细究Python struct 模块
in Python with 0 comment

细究Python struct 模块

in Python with 0 comment
struct — Interpret bytes as packed binary data,将字节与二进制文件相互转化的工具Python struct 模块

关于格式字符串

在Python手册中,给出了C语言中常用类型与Python类型对应的格式符:

格式符C语言类型Python类型
xpad byteno value
ccharstring of length 1
bsigned charinteger
Bunsigned charinteger
?_Boolbool
hshortinteger
Hunsigned shortinteger
iintinteger
Iunsigned intinteger or long
llonginteger
Lunsigned longlong
qlong longlong
Qunsigned longlong long
ffloatfloat
ddoublefloat
schar[]string
pchar[]string
Pvoid *

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)中。这个短整型变量在内存中的存储在大小端模式由下表所示。

地址偏移大端模式小端模式
0x0012(OP0)34(OP1)
0x0134(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

Responses

From now on, bravely dream and run toward that dream.
陕ICP备17001447号