采用小端模式进行解包,并赋值例子:
#python 3.4.3 import struct record = b'raymond \x32\x12\x08\x01\x08' name, serialnum, school, gradelevel = struct.unpack('<10sHHb', record) print(name, serialnum, school, gradelevel)
结果输出如下:
b'raymond ' 4658 264 8
在这里采用struct.unpack解包,把记录record二进制流进行分解,把四项数据保存在name, serialnum, school, gradelevel里面,最后把它们显示出来。其中'<10sHHb'是表示采用小端模式,10个字符,两个无符号数,一个有符号字符类型。
采用命名元组保存解包的数据例子:
#python 3.4.3 import struct from collections import namedtuple record = b'raymond \x32\x12\x08\x01\x08' name, serialnum, school, gradelevel = struct.unpack('<10sHHb', record) print(name, serialnum, school, gradelevel) Student = namedtuple('Student', 'name serialnum school gradelevel') #解包数据保存到元组 print(Student._make(struct.unpack('<10sHHb', record)))
结果输出如下:
b'raymond ' 4658 264 8
Student(name=b'raymond ', serialnum=4658, school=264, gradelevel=8)
在这个例子里,主要使用namedtuple,然后直接调用_make方法,把解包出来的数据,直接保存在命名元组里,不需要创建新的变量保存数据,对于数据的结构化管理很方便。相当二进制流过来解包,直接生成一个结构化的元组。
默认数据对齐方式的例子:
#python 3.4.3
import struct
print('ci:', struct.pack('ci', b'*', 0x12131415))
print('ic:', struct.pack('ic', 0x12131415, b'*'))
print('ci size:', struct.calcsize('ci'))
print('ic size:', struct.calcsize('ic'))
结果输出如下:
ci: b'*\x00\x00\x00\x15\x14\x13\x12'
ic: b'\x15\x14\x13\x12*'
ci size: 8
ic size: 5
从这个例子里,可以看到同样是两个类型c和i的格式,只是排列不一样,导致最后打包出来的二进制流大小不一样,就是由于在连续两个类型之间会产生补齐字符的情况。如果在同一个主机或者同一台电脑里使用下,对于是否添加补充字符是一样的,对于不同的电脑可能是不一样的。所以一般来说对于不同电脑之间的通讯,就需要采用不补充的方式进行填充了,把例子修改如下:
#python 3.4.3
import struct
print('=ci:', struct.pack('=ci', b'*', 0x12131415))
print('=ic:', struct.pack('=ic', 0x12131415, b'*'))
print('=ci size:', struct.calcsize('=ci'))
print('=ic size:', struct.calcsize('=ic'))
结果输出如下:
=ci: b'*\x15\x14\x13\x12'
=ic: b'\x15\x14\x13\x12*'
=ci size: 5
=ic size: 5
以四字对齐,在结构后尾补齐的例子:
#python 3.4.3
import struct
print('llh:', struct.pack('llh', 1, 2, 3))
print('llh0l:', struct.pack('llh0l', 1, 2, 3))
print('llb0l:', struct.pack('llh0l', 1, 2, 3))
结果输出如下:
llh: b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00'
llh0l: b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'
llb0l: b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'
在这个例子里,通过格式串后尾添加零个l的方式来进行四字节对齐,要注意这里格式字符l,而不是数字1。
在struct模块里,定义一个类struct,主要以下方法:
class struct.Struct(format)
返回一个可以按格式format进行操作二进制数据的Struct对象。如果只有一种格式进行解包和打包时,采用此对象比使用函数更高效,因为格式字符串只需要进行处理一次,就可以对不同数据进行解包和打包的操作了。
此对象支持以下方法和属性:
pack(v1, v2, ...)
与pack()函数功能一样,用已经编译好的格式字符串打包。
pack_into(buffer, offset, v1, v2, ...)
与pack_into()函数功能一样,用已经编译好的格式字符串打包。
unpack(buffer)
与unpack()函数功能一样,用已经编译好的格式字符串解包。
unpack_from(buffer, offset=0)
与unpack_from()函数功能一样,用已经编译好的格式字符串解包。
iter_unpack(buffer)
与iter_unpack()函数功能一样,用已经编译好的格式字符串解包。
format
保存构造时传入格式字符串。
size
根据格式字符串进行计算出来需要二进制缓冲区的大小。
例子:
#python 3.4.3
import struct
fmt = struct.Struct('llh')
print(fmt.format)
print(fmt.size)
encode = fmt.pack(1, 2, 3)
print(encode)
print(fmt.unpack(encode))
结果输出如下:
b'llh'
10
b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00'
(1, 2, 3)
蔡军生 QQ:9073204 深圳