这篇文章给大家分享的是有关Python中二进制数据结构Struct有什么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
在C/C++语言中,struct被称为结构体。而在Python中,struct是一个专门的库,用于处理字节串与原生Python数据结构类型之间的转换。
本篇,将详细介绍二进制数据结构struct的使用方式。
struct库包含了一组处理结构值得模块级函数,以及一个Struct类。格式指示符将由字符串格式转换为一种编译表示,这与处理正则表达式得方式类似。
这个转换会耗费一些资源,所以创建一个Struct实例并再这个实例上调用方法时,只完成一次转换,往往会更高效。
Struct支持使用格式指示符将数据打包为字符串,另外支持从字符串解包数据,格式指示符由表示数据类型的字符串和可选的数量及字节序指示符构成。
下面,我们来打包一个元组,将其转换为16进制字节序列,示例如下:
import struct import binascii values = (2, 'lyj'.encode('UTF-8'), 3.8) s = struct.Struct('I 3s f') packed_data = s.pack(*values) print("原值:", values) print("格式指示符:", s.format) print("大小:", s.size, 'bytes') print("打包值:", binascii.hexlify(packed_data))
运行之后,效果如下:
这里的格式指示符为“I 3s f”。前面介绍array数组时,我们已经列出过一个表格。其中I标识一个整型或长整型,3s表示3个字节字符串(lyj),f表示浮点数。
struct库使用unpack()可以从打包的表示数据中抽取数据,这里直接复制上面的打包值,进行测试。示例如下:
import struct import binascii packed_data = binascii.unhexlify(b'020000006c796a0033337340') s = struct.Struct('I 3s f') unpacked_data = s.unpack(packed_data) print("解包值:", unpacked_data)
运行之后,效果如下:
虽然使用unpack()解包基本会得到相同值,但浮点数的值有微小的差别。
默认情况下,值会使用原生C库的字节序(endianness)来编码。Struct的字节序指示符如下表所示:
代码 | 含义 |
---|---|
@ | 原生顺序 |
= | 原生标准 |
< | 小端 |
> | 大端 |
! | 网络顺序 |
示例如下:
import struct import binascii values = (2, 'lyj'.encode('UTF-8'), 3.8) endianness = [ ('@', '原生顺序'), ('=', '原生标准'), ('<', '小端'), ('>', '大端'), ('!', '网络顺序'), ] for code, name in endianness: s = struct.Struct(code + ' I 3s f') packed_data = s.pack(*values) print("格式化字符串:", s.format, ' for ', name) print("大小:", s.size, 'bytes') print("打包:", binascii.hexlify(packed_data)) print("解包:", s.unpack(packed_data))
运行之后,效果如下:
如果想改变字节序来编码,如上面代码所示,只需要改变格式串中提供一个显式的字节序指令,就可以很容易地覆盖这个默认选择。
通常在强调性能的情况下或者向扩展模块传入或传出数据时才会处理二进制打包数据。
为了避免为每个打包结构分配一个新缓冲区所带来的开销,通常情况下,我们使用pack_into()和unpack_from()方法支持直接写入预分配的缓冲区。
示例如下:
import struct import binascii import ctypes import array values = (2, 'lyj'.encode('UTF-8'), 3.8) s = struct.Struct('I 3s f') print("原始值:", values) b = ctypes.create_string_buffer(s.size) print("打包之前(缓冲区的值):", binascii.hexlify(b.raw)) s.pack_into(b, 0, *values) print("打包之后(缓冲区的值):", binascii.hexlify(b.raw)) print("解包:", s.unpack_from(b, 0)) a = array.array('b', b'\0' * s.size) print("打包之前(缓冲区的值):", binascii.hexlify(a)) s.pack_into(a, 0, *values) print('打包之后(缓冲区的值):', binascii.hexlify(a)) print("解包:", s.unpack_from(a, 0))
运行之后,效果如下:
这里通过两种方式,创建缓冲区。其中size属性用于指出缓冲区需要的大小。
感谢各位的阅读!关于“Python中二进制数据结构Struct有什么用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。