Python3标准库:struct二进制数据结构
1. struct二进制数据结构
struct模块包括一些函数,这些函数可以完成字节串与原生Python数据类型(如数字和字符串)之间的转换。
1.1 函数与Struct类
struct提供了一组处理结构值的模块级函数,另外还有一个Struct类。格式指示符将由字符串格式转换为一种编译表示,这与处理正则表达式的方式类似。这个转换会耗费一些资源,所以创建一个Struct实例并在这个实例上调用方法时(不是使用模块级函数)只完成一次转换,这会更高效。下面的例子使用了Struct类。
1.2 打包和解包
Struct支持使用格式指示符将数据打包(packing)为字符串,另外支持从字符串解包(unpacking)数据,格式指示符由表示数据类型的字符和可选的数量及字节序(endianness)指示符构成。
在下面的例子中,指示符要求有一个整型或长整型值、一个两字节字符串以及一个浮点数。格式指示符中包含的空格用来分隔类型指示符,并且在编译格式时会被忽略。
import struct
import binascii values = (1, 'ab'.encode('utf-8'), 2.7)
s = struct.Struct('I 2s f')
packed_data = s.pack(*values) print('Original values:', values)
print('Format string :', s.format)
print('Uses :', s.size, 'bytes')
print('Packed Value :', binascii.hexlify(packed_data))
这个例子将打包的值转换为一个十六进制字节序列,以便用binascii.hexlify()打印,因为有些字符是null。

使用unpack()可以从打包的表示中抽取数据。
import struct
import binascii packed_data = binascii.unhexlify(b'0100000061620000cdcc2c40') s = struct.Struct('I 2s f')
unpacked_data = s.unpack(packed_data)
print('Unpacked Values:', unpacked_data)
将打包值传入unpack(),基本上会得到相同的值(注意浮点值中的微小差别)。

1.3 字符串
默认地,值会使用原生C库的字节序(endianness)来编码。只需在格式串中提供一个显式的字节序指令,就可以很容易地覆盖这个默认选择。
import struct
import binascii values = (1, 'ab'.encode('utf-8'), 2.7)
print('Original values:', values) endianness = [
('@', 'native, native'),
('=', 'native, standard'),
('<', 'little-endian'),
('>', 'big-endian'),
('!', 'network'),
] for code, name in endianness:
s = struct.Struct(code + ' I 2s f')
packed_data = s.pack(*values)
print()
print('Format string :', s.format, 'for', name)
print('Uses :', s.size, 'bytes')
print('Packed Value :', binascii.hexlify(packed_data))
print('Unpacked Value :', s.unpack(packed_data))
根据下表,格式字符串的第一个字符可用于指示打包数据的字节顺序,大小和对齐方式:
|
字符 |
字节顺序 |
大小 |
对齐方式 |
|---|---|---|---|
|
|
按原字节 |
按原字节 |
按原字节 |
|
|
按原字节 |
标准 |
无 |
|
|
小端 |
标准 |
无 |
|
|
大端 |
标准 |
无 |
|
|
网络(=大端) |
标准 |
无 |

1.4 缓冲区
通常在强调性能的情况下或者向扩展模块传入或传出数据时才会处理二进制打包数据。通过避免为每个打包结构分配一个新缓冲区所带来的开销,这些情况可以得到优化。pack_into()和unpack_from()方法支持直接写入预分配的缓冲区。
import array
import binascii
import ctypes
import struct s = struct.Struct('I 2s f')
values = (1, 'ab'.encode('utf-8'), 2.7)
print('Original:', values) print()
print('ctypes string buffer') b = ctypes.create_string_buffer(s.size)
print('Before :', binascii.hexlify(b.raw))
s.pack_into(b, 0, *values)
print('After :', binascii.hexlify(b.raw))
print('Unpacked:', s.unpack_from(b, 0)) print()
print('array') a = array.array('b', b'\0' * s.size)
print('Before :', binascii.hexlify(a))
s.pack_into(a, 0, *values)
print('After :', binascii.hexlify(a))
print('Unpacked:', s.unpack_from(a, 0))
Struct的size属性指出缓冲区需要有多大。

Python3标准库:struct二进制数据结构的更多相关文章
- 8.Python3标准库--数据持久存储与交换
''' 持久存储数据以便长期使用包括两个方面:在对象的内存中表示和存储格式之间来回转换数据,以及处理转换后数据的存储区. 标准库包含很多模块可以处理不同情况下的这两个方面 有两个模块可以将对象转换为一 ...
- Python3 标准库
Python3标准库 更详尽:http://blog.csdn.net/jurbo/article/details/52334345 文本 string:通用字符串操作 re:正则表达式操作 diff ...
- 7.Python3标准库--文件系统
''' Python的标准库中包含大量工具,可以处理文件系统中的文件,构造和解析文件名,还可以检查文件内容. 处理文件的第一步是要确定处理的文件的名字.Python将文件名表示为简单的字符串,另外还提 ...
- 1.Python3标准库--前戏
Python有一个很大的优势便是在于其拥有丰富的第三方库,可以解决很多很多问题.其实Python的标准库也是非常丰富的,今后我将介绍一下Python的标准库. 这个教程使用的书籍就叫做<Pyth ...
- python023 Python3 标准库概览
Python3 标准库概览 操作系统接口 os模块提供了不少与操作系统相关联的函数. >>> import os >>> os.getcwd() # 返回当前的工作 ...
- 比较两个文件的异同Python3 标准库difflib 实现
比较两个文件的异同Python3 标准库difflib 实现 对于要比较两个文件特别是配置文件的差异,这种需求很常见,如果用眼睛看,真是眼睛疼. 可以使用linux命令行工具diff a_file b ...
- python3标准库总结
Python3标准库 操作系统接口 os模块提供了不少与操作系统相关联的函数. ? 1 2 3 4 5 6 >>> import os >>> os.getcwd( ...
- 3.Python3标准库--数据结构
(一)enum:枚举类型 import enum ''' enum模块定义了一个提供迭代和比较功能的枚举类型.可以用这个为值创建明确定义的符号,而不是使用字面量整数或字符串 ''' 1.创建枚举 im ...
- 9.Python3标准库--数据压缩与归档
''' 尽管现代计算机系统的存储能力日益增长,但生成数据的增长是永无休止的. 无损(lossless)压缩算法以压缩或解压缩数据花费的时间来换取存储数据所需要的空间,以弥补存储能力的不足. Pytho ...
随机推荐
- DOCKER 学习笔记4 认识DockerCompose 多容器编排
前言 通过上一节的学习,学会了如何在Linux 环境下搭建Docker并且部署Springboot 项目,并且成功的跑了起来,当然,在生产环境中,不只是需要一个后端的Web 项目,还需要比如 Ngin ...
- Vue 常用三种传值方式
Vue常用的三种传值方式: 父传子 子传父 非父子传值 引用官网一句话:父子组件的关系可以总结为 prop 向下传递,事件向上传递.父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消 ...
- java工具类方法
1.生成16位数字(当时日期时间加随机两位数) public static String getNo16() { String getNo = getNo(); return getNo.substr ...
- LIBCMTD.lib与libcpmtd冲突的解决方法。
error: 1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int) ...
- LeetCode 681. Next Closest Time 最近时刻 / LintCode 862. 下一个最近的时间 (C++/Java)
题目: 给定一个"HH:MM"格式的时间,重复使用这些数字,返回下一个最近的时间.每个数字可以被重复使用任意次. 保证输入的时间都是有效的.例如,"01:34" ...
- C语言寒假大作战04
问题 答案 这个作业属于那个课程 https://edu.cnblogs.c0m/campus/zswxy/CST2019-4 这个作业的要求在哪里 https://edu.cnblogs.com/c ...
- Golang调用Dll案例
Golang调用Dll案例 前言 在家办公已经两个多星期了,目前最大的困难就是网络很差.独自一个人用golang开发调用dll的驱动程序.本来就是半桶水的我,还在为等待打开一个页面而磨平了耐心.本想依 ...
- 源码编译安装MySQL5.7
一.数据库 概述 什么是数据库?简单来说就是存储数据的仓库.这个仓库它会按照一定的数据结构来对数据进行组织和存储.我们可通过数据库提供的多种方法来管理其中的数据 说比较通俗一点就是计算机中的数据库就是 ...
- k8s系列----索引
day1:k8s集群准备搭建和相关介绍 day2:k8spod介绍与创建 day3:k8sService介绍及创建 day4:ingress资源和ingress-controller day5:存储卷 ...
- Linux 发行版本简述
在撰写这篇文章前,先向linux创始人 Linus Torvalds 先生致敬,感谢您二十多年前的无私开源! 其次向二十多年来维护更新的开发者们致敬! Lin ...