python struct模块

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: python struct模块

struct模块



struct模块提供了用于在字节字符串和Python原生数据类型之间的转换,可以用于处理存储在文件中或从网络连接中存储的二进制数据,以及其他数据源。

struct中的pack函数把任意数据类型变成bytes

  • pack(fmt,v1,v2…) ->string
    按照给定的格式fmt, 将数据转换为字节流,并将该字节流返回
  • pack_into(fmt,buffer,offset,v1,v2)->None
    按照给定的格式fmt,将数据转换成字节流,并将字节流写入以offset开始的buffer中( buffer为可写的缓冲区,可用array模块)
  • unpack(fmt,v1,v2)->tuple
    按照给定的格式fmt,解析字节流,并返回解析结果
  • pack_from(fmt,buffer,offset)->tuple
    按照给定的格式fmt,解析以offset开始的缓冲区,并返回解析结果
  • calcsize(fmt)->int
    计算给定的格式fmt占用多少字节的内存,注意对齐方式
打包和解包

struct 支持将数据pack(打包成字节串),并能从字节串中unpack(解包)出数据。

import struct
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))
# binascii.hexlify()将打包的值转换为十六进制字节序列显示出来

格式符中的空格用于分隔各个指示器(indicators), 在编译格式时会被忽略

import struct
values = (1,'ab'.encode("utf-8"),2.7)
s = struct.Struct("I 2s f")
packed_data = s.pack(*values)
unpacked_data = s.unpack(packed_data)
print(unpacked_data)
# 没有分隔符
# 2个整数,1个有3个字符的字符串,一个整数
a = struct.pack("2I3sI", 12, 34, b"abc", 56)
b = struct.unpack("2I3sI", a)
print('a:',a)
print('b:',b)
字节顺序和对齐

默认情况下,pack使用本地C库的字节顺序来编码的。格式化字符串的第一个字符可以用来表示填充数据的字节顺序、大小和对齐方式。

一般情况下,主机字节序小端模式,网络字节序大端模式

如果格式符中没有设置这些,那么默认将使用 @。

print(struct.calcsize("2I3sI"))# 16

上面的三个整型加一个 3 字符的字符串一共占用了 16 个字节

1 个 int 4 字节,3 个字符 3 字节

在 struct的打包过程中,根据特定类型的要求,必须进行字节对齐

由于默认 unsigned int 型占用四个字节,因此要在字符串的位置进行4字节对齐,因此即使是 3 个字符的字符串也要占用 4 个字节。

不定长数据pack

处理不定长的内容的主要思想是把长度和内容一起打包,解包时先解析内容的长度,然后再读取正文

# 对于变长字符串在处理时把字符串的长度当成数据的内容一起打包
s = bytes(s)
data = struct.pack("I%ds"%(len(s),),len(s),s)
# 解包变长字符串
int_size = struct.calcsize("I")
i = struct.unpack("I",data[:int_size])
data = struct.unpack("%ds"%(i[0],),data[int_size:])
# 解包变长字符串时先解包内容的长度,再根据内容的长度解包数据
格式符

缓冲区

可以通过避免为每个打包结构分配新缓冲区的开销来优化

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

  • pack_into(format, buffer, offset, v1, v2, …)
  • unpack_from(format, buffer, offset=0)

在组包拆包时,可以指定所需的偏移量,这让组包拆包变得更加灵活。

import ctypes
import struct
s = struct.Struct('I 2s f')
sbuf = struct.Struct('I 2s f')
values = (1, 'ab'.encode('utf-8'), 2.7)
s.pack_into(sbuf, 0, *values)
res = s.unpack_from(sbuf, 0)
参考

python(29):struct模块_python struct_python开发笔记的博客-CSDN博客

相关文章
|
3月前
|
开发者 Python
如何在Python中管理模块和包的依赖关系?
在实际开发中,通常会结合多种方法来管理模块和包的依赖关系,以确保项目的顺利进行和可维护性。同时,要及时更新和解决依赖冲突等问题,以保证代码的稳定性和可靠性
80 4
|
2月前
|
Python
Python Internet 模块
Python Internet 模块。
128 74
|
3月前
|
算法 数据安全/隐私保护 开发者
马特赛特旋转算法:Python的随机模块背后的力量
马特赛特旋转算法是Python `random`模块的核心,由松本真和西村拓士于1997年提出。它基于线性反馈移位寄存器,具有超长周期和高维均匀性,适用于模拟、密码学等领域。Python中通过设置种子值初始化状态数组,经状态更新和输出提取生成随机数,代码简单高效。
132 63
|
3月前
|
数据可视化 Python
如何在Python中解决模块和包的依赖冲突?
解决模块和包的依赖冲突需要综合运用多种方法,并且需要团队成员的共同努力和协作。通过合理的管理和解决冲突,可以提高项目的稳定性和可扩展性
|
3月前
|
测试技术 Python
手动解决Python模块和包依赖冲突的具体步骤是什么?
需要注意的是,手动解决依赖冲突可能需要一定的时间和经验,并且需要谨慎操作,避免引入新的问题。在实际操作中,还可以结合使用其他方法,如虚拟环境等,来更好地管理和解决依赖冲突😉。
|
26天前
|
Python
[oeasy]python057_如何删除print函数_dunder_builtins_系统内建模块
本文介绍了如何删除Python中的`print`函数,并探讨了系统内建模块`__builtins__`的作用。主要内容包括: 1. **回忆上次内容**:上次提到使用下划线避免命名冲突。 2. **双下划线变量**:解释了双下划线(如`__name__`、`__doc__`、`__builtins__`)是系统定义的标识符,具有特殊含义。
29 3
|
3月前
|
持续交付 Python
如何在Python中自动解决模块和包的依赖冲突?
完全自动解决所有依赖冲突可能并不总是可行,特别是在复杂的项目中。有时候仍然需要人工干预和判断。自动解决的方法主要是提供辅助和便捷,但不能完全替代人工的分析和决策😉。
|
3月前
|
JSON Linux 数据格式
Python模块:从入门到精通,只需一篇文章!
Python中的模块是将相关代码组织在一起的单元,便于重用和维护。模块可以是Python文件或C/C++扩展,Python标准库中包含大量模块,如os、sys、time等,用于执行各种任务。定义模块只需创建.py文件并编写代码,导入模块使用import语句。此外,Python还支持自定义模块和包,以及虚拟环境来管理项目依赖。
Python模块:从入门到精通,只需一篇文章!
|
3月前
|
Python
Python的模块和包
总之,模块和包是 Python 编程中非常重要的概念,掌握它们可以帮助我们更好地组织和管理代码,提高开发效率和代码质量
59 5
|
3月前
|
Python
在Python中,可以使用内置的`re`模块来处理正则表达式
在Python中,可以使用内置的`re`模块来处理正则表达式
85 5

热门文章

最新文章