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