一、模块介绍
官方网址:
此模块可以执行 Python 值和以 Python bytes 对象表示的 C 结构之间的转换。 这可以被用来处理存储在文件中或是从网络连接等其他来源获取的二进制数据。 它使用 格式字符串 作为 C 结构布局的精简描述以及与 Python 值的双向转换。
二、简单使用
# 官方文档地址:https://docs.python.org/zh-cn/3/library/struct.html
from struct import *
from collections import namedtuple
# 对python整型,打包
print("h:c类型short:",pack('h', 1))
print("l:c类型long:",pack('l', 1))
print("h、l混用结果:",pack('hl', 1, 1)) # h:c类型short,l:c类型long
print("l、h混用结果:",pack('lh', 1, 1))
print("h、h混用结果:",pack('hh', 1, 1))
print("l、l混用结果:",pack('ll', 1, 1))
# 对C类型字节,解包
print("对c类型short解包:",unpack('h', b'\x01\x00'))
print("对c类型long解包:",unpack('l', b'\x01\x00\x00\x00'))
print("对h、l混用结果解包:",unpack('hl', b'\x01\x00\x00\x00\x01\x00\x00\x00')) # h:c类型short,l:c类型long
print("对l、h混用结果解包:",unpack('lh', b'\x01\x00\x00\x00\x01\x00'))
print("对h、h混用结果解包:",unpack('hh', b'\x01\x00\x01\x00'))
print("对l、l混用结果解包:",unpack('ll', b'\x01\x00\x00\x00\x01\x00\x00\x00'))
# 小结:通过上述操作,发现h、l和l、l的混用打包是一致的,而h、l和l、h打包却不一致。
# 解包的字段可通过将它们赋值给变量或将结果包装为一个具名元组来命名:
record = b'raymond \x32\x12\x08\x01\x08' # 前10个是字符串
name, serialnum, school, gradelevel = unpack('<10sHHb', record) # 解包对象是record,<10代表前10个字节作为解包的一部分,s表示字节串char[],H代表unsigned short,b代表signed char
print(name)
print(serialnum)
print(school)
print(gradelevel)
Student01 = namedtuple('Student', 'name serialnum school gradelevel')
print(Student01._make(unpack('<10sHHb', record))) # Student(name=b'raymond ', serialnum=4658, school=264, gradelevel=8)
Student02 = Student01(*unpack('<10sHHb', record)) # 元组赋值方式
print(Student02.serialnum) # 元组取值方式
# 格式字符的顺序可能对大小产生影响,因为满足对齐要求所需的填充是不同的:
print(pack('ci', b'*', 0x12131415)) # b'*\x00\x00\x00\x12\x13\x14\x15'
print(pack('ic', 0x12131415, b'*')) # b'\x12\x13\x14\x15*'
print(calcsize('ci')) # 8, 以字节为单位返回格式字符串所描述的结构的大小。
print(calcsize('ic')) # 5
# 以下格式 'llh0l' 指定在末尾有两个填充字节,假定 long 类型按 4 个字节的边界对齐:
print(pack('llh0l', 1, 2, 3)) # b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
# Struct(format)对象的使用
obj = Struct("h")
print(obj.pack(1)) # 效果等价于 pack('h', 1)
'''等价情况
pack(v1, v2, ...)
等价于 pack() 函数,使用了已编译的格式。 (len(result) 将等于 size。)
pack_into(buffer, offset, v1, v2, ...)
等价于 pack_into() 函数,使用了已编译的格式。
unpack(buffer)
等价于 unpack() 函数,使用了已编译的格式。 缓冲区的字节大小必须等于 size。
unpack_from(buffer, offset=0)
等价于 unpack_from() 函数,使用了已编译的格式。 缓冲区的字节大小从位置 offset 开始必须至少为 size。
iter_unpack(buffer)
等价于 iter_unpack() 函数,使用了已编译的格式。 缓冲区的大小必须为 size 的整数倍。
3.4 新版功能.
format
用于构造此 Struct 对象的格式字符串。
在 3.7 版更改: 格式字符串类型现在是 str 而不再是 bytes。
size
计算出对应于 format 的结构大小(亦即 pack() 方法所产生的字节串对象的大小)。
'''
三、常用场景
1、socket协议的分包或打包使用到的大端序字节生成
2、python与C类型的类型转换(官方所述)