python struct (二)

本文通过Python中的struct模块实现对二进制数据的打包与解包操作,并利用binascii模块进行辅助验证。演示了如何创建特定格式的字符串,并将其转换为整数元组。

代码如下:

# -*- coding:utf-8 -*-
import struct
import binascii

str_pack = ''

var = chr(6)
str_pack += var

var = chr(0)
str_pack += var

var = chr(0)
str_pack += var

var = chr(0)
str_pack += var


var = chr(7)
str_pack += var

var = chr(0)
str_pack += var

var = chr(0)
str_pack += var

var = chr(0)
str_pack += var

unpacked_data = struct.unpack('II',str_pack)

print ('str_pack type: ',type(str_pack))
print ('unpacked_data type: ',type(unpacked_data))

print('str Value :', binascii.hexlify(str_pack))

print unpacked_data

print unpacked_data[0]

print unpacked_data[1]

运行结果如下:

('str_pack type: ', <type 'str'>)
('unpacked_data type: ', <type 'tuple'>)
('str Value :', '0600000007000000')
(6, 7)
6
7

Process finished with exit code 0
<think>我们正在讨论Pythonstruct模块。根据引用,struct模块主要用于处理进制数据,特别是在需要将Python数据类型转换为C语言中的结构体类型(以字节流形式表示)时,或者反过来解析字节流为Python数据类型。这在网络通信、文件读写等场景中非常常见。 主要功能: 1. 打包(pack):将Python数据按照指定的格式转换为字节流(bytes)。 2. 解包(unpack):将字节流按照指定的格式解析为Python数据类型。 3. 计算大小(calcsize):计算给定格式的字节流所占用的字节数。 引用[1]和[2]提到,struct模块提供了模块级函数,同时也提供了Struct类。使用Struct类通常更高效,特别是需要重复使用相同格式字符串时。 格式字符串: 格式字符串用于指定数据的类型和顺序。例如: - 'i' 表示整数(int),通常是4个字节 - 'f' 表示浮点数(float),通常是4个字节 - 's' 表示字节串(bytes),通常前面可以加数字表示长度,如'10s'表示10个字节的字符串 - 等等 此外,格式字符串的第一个字符可以用来指定字节顺序、大小和对齐方式(即字节序和对齐方式): - '@':本地字节顺序(默认),大小和对齐方式是标准的(根据系统) - '=':使用标准大小,忽略字节顺序(通常用于小端) - '<':小端(little-endian) - '>':大端(big-endian) - '!':网络字节顺序(即大端) 常用函数: 1. struct.pack(format, v1, v2, ...) -> bytes 按照格式字符串format打包数据v1, v2, ...,返回一个字节对象。 2. struct.unpack(format, buffer) -> tuple 根据格式字符串format从缓冲区buffer(通常是字节对象)中解包数据,返回一个元组。 3. struct.calcsize(format) -> int 返回给定格式字符串format所对应的结构体占用的字节数。 4. 使用Struct类(推荐重复使用): s = struct.Struct(format) packed_data = s.pack(v1, v2, ...) unpacked_data = s.unpack(buffer) 示例(参考引用[4]): 打包一个8个字节的字符串(使用大端字节序): import struct s = 'moddemod'.encode() # 转换为字节串 r1 = struct.pack('>8s', s) # 大端,8个字节的字符串 r2, = struct.unpack('>8s', r1) # 解包,注意unpack返回的是元组,这里用逗号解包 print(r2.decode()) # 输出:moddemod 注意:在解包时,返回的是元组,即使只有一个元素。所以上面的例子中,使用`r2, =`来解包元组,将第一个元素赋给r2。 另一个例子:打包整数和浮点数 format = '>if' # 大端,一个整数(4字节)和一个浮点数(4字节) data = struct.pack(format, 10, 3.14) # 解包 values = struct.unpack(format, data) # 返回元组 (10, 3.14) 注意:打包和解包使用的格式字符串必须一致,否则结果可能错误。 使用Struct类可以提高效率,特别是在多次使用相同格式时: s = struct.Struct('>if') packed_data = s.pack(10, 3.14) unpacked_data = s.unpack(packed_data) 计算大小: struct.calcsize('>if') # 返回8,因为一个int和一个float各4字节 注意事项: 1. 格式字符串中的类型和实际数据必须匹配,否则会出错。 2. 对于字符串,使用's'格式时,需要指定长度(如'10s'),并且打包时如果字符串长度超过指定长度会被截断,不足则会用空字节(b'\x00')填充。 3. 在解包时,必须提供与格式字符串匹配的字节流长度,否则会出错。 应用场景: 1. 网络编程:在发送数据前打包,接收数据后解包。 2. 文件读写:读写进制文件,如BMP图像文件头、自定义进制格式等。 3. 与C语言程序交互:通过进制数据交换。 总结:struct模块是Python中处理进制数据的重要工具,它提供了一系列函数和类来实现Python数据类型与C结构体之间的转换。 下面我们用一个综合示例来演示struct模块的使用:</think>### Python `struct` 模块详解 `struct` 模块是 Python 中处理进制数据的核心工具,主要用于实现 Python 数据类型与 C 语言结构体之间的转换,以及处理进制流数据(如网络传输、文件读写)。以下是核心功能和使用方法: #### 一、核心功能 1. **数据类型转换** 将 Python 基本类型(int, float, char 等)转换为进制字节流,或反向解析 2. **字节序控制** 处理不同系统的字节序(大端/小端)问题 3. **内存对齐** 控制数据在内存中的对齐方式 4. **进制数据处理** 适用于网络通信、文件格式解析(如图像/音频头)、硬件交互等场景[^1][^2] #### 、核心函数与方法 | 函数/方法 | 作用描述 | 示例 | |-----------------------|--------------------------------------------------------------------------|-------------------------------| | `pack(format, v1, v2...)` | 将 Python 值按格式打包为进制字节串 | `struct.pack('>i', 255)` | | `unpack(format, buffer)` | 将进制数据按格式解包为 Python 元组 | `struct.unpack('>2s', b'AB')` | | `calcsize(format)` | 计算给定格式的字节长度 | `struct.calcsize('if')` → 8 | | `Struct(format)` 类 | 高效处理重复格式(推荐) | `s = struct.Struct('>f')` | #### 三、格式字符串详解 格式字符串由两部分组成: 1. **字节序标识符**(首位字符) ```python '>' # 大端字节序(网络标准)[^4] '<' # 小端字节序(Intel x86) '@' # 本地字节序(默认) '!' # 网络字节序(同 >) ``` 2. **类型标识符**(核心格式) | 字符 | C 类型 | Python 类型 | 字节数 | |------|----------------|---------------|--------| | `i` | `int` | `int` | 4 | | `f` | `float` | `float` | 4 | | `d` | `double` | `float` | 8 | | `c` | `char` | `bytes` (1) | 1 | | `s` | `char[]` | `bytes` | n | | `?` | `bool` | `bool` | 1 | #### 四、完整使用示例 ```python import struct # 1. 打包数据(大端字节序:1个整数 + 5字节字符串) data = struct.pack('>i5s', 1024, b'hello') print(data) # b'\x00\x00\x04\x00hello' # 2. 解包数据 unpacked = struct.unpack('>i5s', data) print(unpacked) # (1024, b'hello') # 3. 使用Struct类(高效重复操作) s = struct.Struct('>f 10s ?') # 大端浮点 + 10字节字符串 + 布尔 packed = s.pack(3.14, b'Python', True) print(s.unpack(packed)) # (3.14, b'Python', True) # 4. 计算数据大小 print(struct.calcsize('>2id')) # 16 = 2*4(int) + 8(double) ``` #### 五、典型应用场景 1. **网络协议处理** ```python # 解析TCP头部(大端序) tcp_header = struct.unpack('>HHIIBBHHH', raw_data[:20]) ``` 2. **文件格式解析** ```python # 读取BMP文件头 with open('image.bmp', 'rb') as f: header = f.read(14) _, size, _, offset = struct.unpack('<2sI2I', header) ``` 3. **硬件寄存器读写** ```python # 控制硬件寄存器(小端32位整数) register_value = struct.pack('<I', 0xABCDEF00) write_to_hardware(register_value) ``` #### 六、注意事项 1. **数据对齐** 使用 `@` 时自动添加填充字节(如 `struct.calcsize('ic')` → 8 而非 5) 2. **字符串处理** 格式 `Ns` 必须指定长度(如 `10s`),不足补空字节 `\x00` 3. **类型匹配** 输入值类型必须与格式字符严格匹配,否则抛出 `struct.error` > 通过 `struct` 模块,Python 可高效处理底层进制数据,实现与 C 程序的互操作,适合网络编程、文件解析和硬件交互等场景[^1][^3]。 --- ### 相关问题 1. **如何处理不同字节序(大端/小端)的系统间数据交换?** 2. **`struct` 模块与 `ctypes` 模块在进制数据处理上有何异同?** 3. **如何用 `struct` 解析复杂的进制文件格式(如 PNG/MP3)?** 4. **在 Python 中如何实现自定义进制协议的编码/解码?** [^1]: Python struct 模块基础概念 [^2]: Struct 类与模块级函数对比 [^3]: 进制数据与 Buffer 协议 [^4]: pack/unpack 实际应用示例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值