百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Python 中 struct 模块的用法_pythonstring模块

itomcoil 2025-10-02 20:41 10 浏览

Python 为了保持语言的简洁,仅仅为用户提供了几种简单的数据结构:int, float, str, list, dicttuple。不同于编译型语言 C/C++,在 Python 中,我们往往不需要关心不同类型的变量在解释器内部的实现方式。例如,对于一个长整形数据,我们在 Python 2 中可以直接写成 a=123456789012345L,而不用去考虑变量 a 占了几个字节。这种抽象的方式为程序的编写提供了足够的支持,但是在某些情况下(比如读写二进制文件,进行网络 Raw Socket 编程)的时候,我们需要一些其他模块来实现我们关于变量长度控制的需求。

struct 模块

当我们在 Python 中跟二进制数据打交道的时候,就要用到 struct 这个模块了。struct 模块为 Python 与 C 的混合编程,处理二进制文件以及进行网络协议交互提供了便利。理解这个模块主要需要理解三个函数:

struct.pack(fmt, v1, v2, ...)

struct.unpack(fmt, string)

struct.calcsize(fmt)

第一个函数 pack 负责将不同的变量打包在一起,成为一个字节字符串,即类似于 C 语言中的字节流。第二个函数 unpack 将字节字符串解包成为变量。第三个函数 calsize 计算按照格式 fmt 打包的结果有多少个字节。这里打包格式 fmt 确定了将变量按照什么方式打包成字节流,其包含了一系列的格式字符串。这里就不再给出不同格式字符串的含义了,详细细节可以参照 Python Doc (struct).

使用 struct 打包定长结构

一般而言,在使用 struct 的时候,要打包的数据都是定长的。定长的数据代表你需要明确给出要打包的或者解包的数据长度,否则打包解包函数将会出错。下面用例子说明什么是定长打包:

import struct

a = struct.pack("2I3sI", 12, 34, "abc", 56)

b = struct.unpack("2I3sI", a)

print b

## 输出 (12, 34, 'abc', 56)

上面的代码将两个整数 12 和 34,一个字符串 “abc” 和一个整数 56 一起打包成为一个字节字符流,然后再解包。其中打包格式中明确指出了打包的长度:"2I" 表明起始是两个unsigned int"3s" 表明长度为4的字符串,最后一个 "I" 表示最后紧跟一个 unsigned int。所以上面的打印 b 输出结果是:(12, 34, ‘abc’, 56)。

我们可以调用 calcsize() 来计算 "2I3sI" 这个模式占用的字节数:

print struct.calcsize("2I3sI")

## 输出 16

可以看到上面的三个整型加一个 3 字符的字符串一共占用了 16 个字节。为什么会是 16 个字节呢?不应该是 15 个字节吗?其实,在 struct 的打包过程中,根据特定类型的要求,必须进行字节对齐。由于默认 unsigned int 型占用四个字节,因此要在字符串的位置进行4字节对齐,因此即使是 3 个字符的字符串也要占用 4 个字节。

再看一下不需要字节对齐的模式:

print struct.calcsize("2Is")

## 输出 9

由于单字符出现在两个整型之后,不需要进行字节对齐,所以输出结果是 9.

需要指出的是,对于 unpack 而言,只要 fmt 对应的字节数和字节字符串 string 的字节数一致,就可以成功的进行解析,否则 unpack 函数将抛出异常。例如我们也可以使用如下的 fmt 解析出 a

c = struct.unpack("2I2sI", a)

print struct.calcsize("2I2sI")

print c

## 输出 16 (12, 34, 'ab', 56)

可以看到这里 unpack 解析出了字符串的前两个字符,没有产生任何问题。

struct 处理不定长数据

在上一节的介绍中,我们看到了在使用 packunpack 的过程中,我们需要明确的指出打包模式中每个位置的长度。比如格式 "2I3sI" 就明确指出了整型的个数和字符串的个数。有时候,我们还可能会需要处理变长的打包数据。

变长字符串的打包

例如我们在程序中可能会得到一个字符串 s,这个 s 没有一个固定的长度,所以我们每次打包的时候都需要将 s 的长度也打包到一起,这样我们才能进行正确的解包。其实,这种情况在处理网络数据包中非常常见。在使用网络编程的时候,我们可能利用报文的第一个字段记录报文的长度。每次读取报文的时候,我们先读取报文的第一个字段,获取其长度之后在处理报文内容。

我们可以采用两种方式处理这种情况:

s = bytes(s, 'utf-8') # Or other appropriate encoding

struct.pack("I%ds" % (len(s),), len(s), s)

或者

struct.pack("I", len(s)) + s

第一种方式先将报文转变成为字节码,然后获取字节码的长度,将长度嵌入到打包之后的报文中去。可以看到格式字符串中的 "I" 就用来记录报文的长度。第二种方式是直接将字符串的长度打包成字节字符串,再跟原始字符串做一个连接操作。

变长字符串的解包

根据上面的打包方式,我们可以轻松的解开打包串:

int_size = struct.calcsize("I")

(i,), data = struct.unpack("I", data[:int_size]), data[int_size:]

data_content = data[i:]

由于报文的长度 len(s) 我们使用定长的整型 "I" 进行了打包,所以解包的时候我们可以先将报文长度获取出来,之后再根据报文长度读取报文内容。


相关推荐

python创建文件夹,轻松搞定,喝咖啡去了

最近经常在录视频课程,一个课程下面往往有许多小课,需要分多个文件夹来放视频、PPT和案例,这下可好了,一个一个手工创建,手酸了都做不完。别急,来段PYTHON代码,轻松搞定,喝咖啡去了!import...

如何编写第一个Python程序_pycharm写第一个python程序

一、第一个python程序[掌握]python:python解释器,将python代码解释成计算机认识的语言pycharm:IDE(集成开发环境),写代码的一个软件,集成了写代码,...

Python文件怎么打包为exe程序?_python3.8打包成exe文件

PyInstaller是一个Python应用程序打包工具,它可以将Python程序打包为单个独立可执行文件。要使用PyInstaller打包Python程序,需要在命令行中使用py...

官方的Python环境_python环境版本

Python是一种解释型编程开发语言,根据Python语法编写出来的程序,需要经过Python解释器来进行执行。打开Python官网(https://www.python.org),找到下载页面,选择...

[编程基础] Python配置文件读取库ConfigParser总结

PythonConfigParser教程显示了如何使用ConfigParser在Python中使用配置文件。文章目录1介绍1.1PythonConfigParser读取文件1.2Python...

Python打包exe软件,用这个库真的很容易

初学Python的人会觉得开发一个exe软件非常复杂,其实不然,从.py到.exe文件的过程很简单。你甚至可以在一天之内用Python开发一个能正常运行的exe软件,因为Python有专门exe打包库...

2025 PyInstaller 打包说明(中文指南),python 打包成exe 都在这里

点赞标记,明天就能用上这几个技巧!linux运维、shell、python、网络爬虫、数据采集等定定做,请私信。。。PyInstaller打包说明(中文指南)下面按准备→基本使用→常用...

Python自动化办公应用学习笔记40—文件路径2

4.特殊路径操作用户主目录·获取当前用户的主目录路径非常常用:frompathlibimportPathhome_dir=Path.home()#返回当前用户主目录的Path对象...

Python内置tempfile模块: 生成临时文件和目录详解

1.引言在Python开发中,临时文件和目录的创建和管理是一个常见的需求。Python提供了内置模块tempfile,用于生成临时文件和目录。本文将详细介绍tempfile模块的使用方法、原理及相关...

python代码实现读取文件并生成韦恩图

00、背景今天战略解码,有同学用韦恩图展示各个产品线的占比,效果不错。韦恩图(Venndiagram),是在集合论数学分支中,在不太严格的意义下用以表示集合的一种图解。它们用于展示在不同的事物群组之...

Python技术解放双手,一键搞定海量文件重命名,一周工作量秒搞定

摘要:想象一下,周五傍晚,办公室的同事们纷纷准备享受周末,而你,面对着堆积如山的文件,需要将它们的文件名从美国日期格式改为欧洲日期格式,这似乎注定了你将与加班为伍。但别担心,Python自动化办公来...

Python路径操作的一些基础方法_python路径文件

带你走进@机器人时代Discover点击上面蓝色文字,关注我们Python自动化操作文件避开不了路径操作方法,今天我们来学习一下路径操作的一些基础。Pathlib库模块提供的路径操作包括路径的...

Python爬取下载m3u8加密视频,原来这么简单

1.前言爬取视频的时候发现,现在的视频都是经过加密(m3u8),不再是mp4或者avi链接直接在网页显示,都是经过加密形成ts文件分段进行播放。今天就教大家如果通过python爬取下载m3u8加密视频...

探秘 shutil:Python 高级文件操作的得力助手

在Python的标准库中,shutil模块犹如一位技艺精湛的工匠,为我们处理文件和目录提供了一系列高级操作功能。无论是文件的复制、移动、删除,还是归档与解压缩,shutil都能以简洁高效的方式完成...

怎么把 Python + Flet 开发的程序,打包为 exe ?这个方法很简单!

前面用Python+Flet开发的“我的计算器v3”,怎么打包为exe文件呢?这样才能分发给他人,直接“双击”运行使用啊!今天我给大家分享一个简单的、可用的,把Flet开发的程序打包为...