Struct模块到底有多实用?一个知识点立马学习

嗨害大家好鸭!我是小熊猫🖤

今天来给大家讲讲一个非常实用的python模块( •̀ ω •́ )✧


struct模块提供了用于在字节字符串和Python原生数据类型之间转换函数,比如数字和字符串。

该模块作用是完成Python数值和C语言结构体的Python字符串形式间的转换。

这可以用于处理存储在文件中或从网络连接中存储的二进制数据,以及其他数据源。


有什么python相关报错解答自己不会的、或者源码资料/模块安装/女装大佬精通技巧
都可以来这里:(https://jq.qq.com/?_wv=1027&k=2Q3YTfym)或者+V:python10010问我

1. 模块函数和Struct类

它除了提供一个Struct类之外,

还有许多模块级的函数用于处理结构化的值。

这里有个格式符(Format specifiers)的概念,

是指从字符串格式转换为已编译的表示形式,

类似于正则表达式的处理方式。

通常实例化Struct类,

调用类方法来完成转换,

比直接调用模块函数有效的多。

下面的例子都是使用Struct类。

2. Packing(打包)和Unpacking(解包)

Struct支持将数据packing(打包)成字符串,

并能从字符串中逆向unpacking(解压)出数据。

在本例中,格式指定器(specifier)需要一个整型或长整型,

一个两个字节的string,和一个浮点数。

格式符中的空格用于分隔各个指示器(indicators),

在编译格式时会被忽略。

import struct
python学习交流群:660193417###

import binascii

values = (1, 'ab'.encode('utf-8'), 2.7)
s = struct.Struct('I 2s f')
packed_data = s.pack(*values)

print('原始值:', values)
print('格式符:', s.format)
print('占用字节:', s.size)
print('打包结果:', binascii.hexlify(packed_data))

# output
原始值: (1, b'ab', 2.7)
格式符: b'I 2s f'
占用字节: 12
打包结果: b'0100000061620000cdcc2c40'

这个示例将打包的值转换为十六进制字节序列,

用binascii.hexlify()方法打印出来。

使用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_data)

# output
解包结果: (1, b'ab', 2.700000047683716)

将打包的值传给unpack(),基本上返回相同的值(浮点数会有差异)。

3. 字节顺序/大小/对齐

默认情况下,pack是使用本地C库的字节顺序来编码的。

格式化字符串的第一个字符可以用来表示填充数据的字节顺序、大小和对齐方式,如下表所描述的:

在这里插入图片描述
如果格式符中没有设置这些,那么默认将使用 @。

本地字节顺序是指字节顺序是由当前主机系统决定。

比如:Intel x86和AMD64(x86-64)使用小字节序;

Motorola 68000和 PowerPC G5使用大字节序。

ARM和Intel安腾支持切换字节序。

可以使用sys.byteorder查看当前系统的字节顺序。

本地大小(Size)和对齐(Alignment)是由c编译器的sizeof表达式确定的。它与本地字节顺序对应。

标准大小由格式符确定,下面会讲各个格式的标准大小。

示例:

import struct
import binascii

values = (1, 'ab'.encode('utf-8'), 2.7)
print('原始值  : ', 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('格式符  : ', s.format, 'for', name)
    print('占用字节: ', s.size)
    print('打包结果: ', binascii.hexlify(packed_data))
    print('解包结果: ', s.unpack(packed_data))

# output
原始值  :  (1, b'ab', 2.7)

格式符  :  b'@ I 2s f' for native, native
占用字节:  12
打包结果:  b'0100000061620000cdcc2c40'
解包结果:  (1, b'ab', 2.700000047683716)

格式符  :  b'= I 2s f' for native, standard
占用字节:  10
打包结果:  b'010000006162cdcc2c40'
解包结果:  (1, b'ab', 2.700000047683716)

格式符  :  b'< I 2s f' for little-endian
占用字节:  10
打包结果:  b'010000006162cdcc2c40'
解包结果:  (1, b'ab', 2.700000047683716)

格式符  :  b'> I 2s f' for big-endian
占用字节:  10
打包结果:  b'000000016162402ccccd'
解包结果:  (1, b'ab', 2.700000047683716)

格式符  :  b'! I 2s f' for network
占用字节:  10
打包结果:  b'000000016162402ccccd'
解包结果:  (1, b'ab', 2.700000047683716)

4. 格式符

格式符对照表如下:

在这里插入图片描述

5. 缓冲区

将数据打包成二进制通常是用在对性能要求很高的场景。

在这类场景中可以通过避免为每个打包结构分配新缓冲区的开销来优化。

pack_into()和unpack_from()方法支持直接写入预先分配的缓冲区。


今天的知识点就到这里啦,希望这篇文章对你有所帮助~

我是小熊猫,咱下篇文章再见啦(✿◡‿◡)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值