笔记-Python中的struct模块

了解c语言的人,一定会知道struct结构体在c语言中的作用,它定义了一种结构,里面包含不同类型的数据(int,char,bool等等),方便对某一结构对象进行处理。而在网络通信当中,大多传递的数据是以二进制流(binary data)存在的。当传递字符串时,不必担心太多的问题,而当传递诸如int、char之类的基本数据的时候,就需要有一种机制将某些特定的结构体类型打包成二进制流的字符串然后再网络传输,而接收端也应该可以通过某种机制进行解包还原出原始的结构体数据。python中的struct模块就提供了这样的机制,该模块的主要作用就是对python基本类型值与用python字符串格式表示的C struct类型间的转化(This module performs conversions between Python values and C structs represented as Python strings.)。stuct模块提供了很简单的几个函数,下面写几个例子。

1、基本的pack和unpack

struct提供用format specifier方式对数据进行打包和解包(Packing and Unpacking)。例如:
import struct
import binascii
values = (1, 'abc', 2.7)
s = struct.Struct('I3sf')
packed_data = s.pack(*values)
unpacked_data = s.unpack(packed_data)print 'Original values:', values
print 'Format string :', s.format
print 'Uses :', s.size, 'bytes'
print 'Packed Value :', binascii.hexlify(packed_data)
print 'Unpacked Type :', type(unpacked_data), ' Value:', unpacked_data

输出:

Original values: (1, 'abc', 2.7)
Format string : I3sf
Uses : 12 bytes
Packed Value : 0100000061626300cdcc2c40
Unpacked Type : <type 'tuple'>  Value: (1, 'abc', 2.700000047683716)

代码中,首先定义了一个元组数据,包含int、string、float三种数据类型,然后定义了struct对象,并制定了format‘I3sf’,I 表示int,3s表示三个字符长度的字符串,f 表示 float。最后通过struct的pack和unpack进行打包和解包。通过输出结果可以发现,value被pack之后,转化为了一段二进制字节串,而unpack可以把该字节串再转换回一个元组,但是值得注意的是对于float的精度发生了改变,这是由一些比如操作系统等客观因素所决定的。打包之后的数据所占用的字节数与C语言中的struct十分相似。定义format可以参照官方api提供的对照表:

在这里插入图片描述

2、字节顺序

另一方面,打包的后的字节顺序默认上是由操作系统的决定的,当然struct模块也提供了自定义字节顺序的功能,可以指定大端存储、小端存储等特定的字节顺序,对于底层通信的字节顺序是十分重要的,不同的字节顺序和存储方式也会导致字节大小的不同。在format字符串前面加上特定的符号即可以表示不同的字节顺序存储方式,例如采用小端存储 s = struct.Struct(‘<I3sf’)就可以了。官方api library 也提供了相应的对照列表:

在这里插入图片描述

3、利用buffer,使用pack_into和unpack_from方法

使用二进制打包数据的场景大部分都是对性能要求比较高的使用环境。而在上面提到的pack方法都是对输入数据进行操作后重新创建了一个内存空间用于返回,也就是说我们每次pack都会在内存中分配出相应的内存资源,这有时是一种很大的性能浪费。struct模块还提供了pack_into() 和 unpack_from()的方法用来解决这样的问题,也就是对一个已经提前分配好的buffer进行字节的填充,而不会每次都产生一个新对象对字节进行存储。

import struct
import binascii
import ctypesvalues = (1, 'abc', 2.7)
s = struct.Struct('I3sf')
prebuffer = ctypes.create_string_buffer(s.size)
print 'Before :',binascii.hexlify(prebuffer)
s.pack_into(prebuffer,0,*values)
print 'After pack:',binascii.hexlify(prebuffer)
unpacked = s.unpack_from(prebuffer,0)
print 'After unpack:',unpacked

输出:

Before : 000000000000000000000000
After pack: 0100000061626300cdcc2c40
After unpack: (1, 'abc', 2.700000047683716)

对比使用pack方法打包,pack_into 方法一直是在对prebuffer对象进行操作,没有产生多余的内存浪费。另外需要注意的一点是,pack_into和unpack_from方法均是对string buffer对象进行操作,并提供了offset参数,用户可以通过指定相应的offset,使相应的处理变得更加灵活。例如,我们可以把多个对象pack到一个buffer里面,然后通过指定不同的offset进行unpack:

import struct
import binascii
import ctypesvalues1 = (1, 'abc', 2.7)
values2 = ('defg',101)
s1 = struct.Struct('I3sf')
s2 = struct.Struct('4sI')prebuffer = ctypes.create_string_buffer(s1.size+s2.size)
print 'Before :',binascii.hexlify(prebuffer)
s1.pack_into(prebuffer,0,*values1)
s2.pack_into(prebuffer,s1.size,*values2)
print 'After pack:',binascii.hexlify(prebuffer)
print s1.unpack_from(prebuffer,0)
print s2.unpack_from(prebuffer,s1.size)

输出:

Before : 0000000000000000000000000000000000000000
After pack: 0100000061626300cdcc2c406465666765000000
(1, 'abc', 2.700000047683716)
('defg', 101)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/848648.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【简报】VITA 74 (VNX)B

1 为什么向AMSAT社区提及VPX / VNX 1.1VPX是包括卫星在内的最新一代军用车辆增长最快的标准 VITA 65 – 面向地面车辆的 OpenVPX文献检索将揭示在许多商业和军事坚固型系统应用中的广泛应用VITA 78 – AFRL和工业界正在开发用于卫星的“SpaceVPX”和“Space VPX Lite” 1.2 …

人工智能_机器学习097_PCA数据降维算法_数据去中心化_特征值_特征向量_EVD特征值分解原来和代码实现---人工智能工作笔记0222

降维算法的原理,一会咱们再看,现在先看一下,算法 可以看到PCA算法的,原理和过程,我们先看一下代码 为了说明PCA原理,这里,我们,先来计算一下X的方差,可以看到 先把数据进行去中心化,也就是用数据,减去数据的平均值. B = X-X.mean(axis=0) 这段代码是用于计算矩阵X的每一列减去该…

EE trade:通货膨胀对老百姓意味着什么

通货膨胀&#xff0c;是经济领域中的一个常见现象&#xff0c;对社会各阶层尤其是普通老百姓的生活产生了深远影响。理解通货膨胀对老百姓的真实含义&#xff0c;可以帮助我们更好地应对日常生活的变化与挑战。 1. 生活成本的上升 最直接的影响体现在生活成本上。通货膨胀会导致…

Linux操作系统:Redis在虚拟环境下的安装与部署

Redis下载方法 最近部署项目的时候用到了Redis&#xff0c;自己在安装的时候也碰到了一些列问题最终安装成功&#xff0c;记录一下自己的安装历程。前期准备&#xff1a; 服务器Linux版本&#xff1a;Centos8.4 64位&#xff08;http://isoredirect.centos.org/centos/8/isos/…

如何使用Python提取Excel中固定单元格的内容

正文共&#xff1a;1234 字 31 图&#xff0c;预估阅读时间&#xff1a;1 分钟 之前转载了颜总的Python环境搭建文章&#xff08;Python办公自动化—环境搭建&#xff09;&#xff0c;很久过去了&#xff0c;颜总也没有再更新。现在我有一个需求&#xff0c;就是我手上有大量格…

Android Studio 下载 | 安装 | 下载 SDK | 中文插件 | 卸载

文章目录 下载安装包安装下载 SDK中文插件卸载 下载安装包 下载 Android Studio 和应用工具 - Android 开发者 | Android Developers 点击下载 Android Studio。 在协议最下方勾选同意&#xff08;第一次用最好还是看一眼&#xff09;&#xff0c;再点击 Dowload Android Stu…

css文字超出元素省略,单行、多行省略

通用CSS .box {width: 500px;border: 1px solid red;padding: 10px;line-height: 24px;} 1.单行省略 .singe-line {text-overflow: ellipsis;overflow: hidden;word-break: break-all;white-space: nowrap;}<p>单行省略</p><div class"singe-line box&qu…

GraphQL(5):使用Mutations修改数据

GraphQL中的使用Mutation查询&#xff0c;下面介绍详细操作&#xff0c;新建一个mutation.js文件。 1 定义schema 1.1 定义模型对象 &#xff08;1&#xff09;定义输入模型 input AccountInput {name: Stringage: Intsex: Stringdepartment: String} &#xff08;2&#xf…

攻防世界---misc---Ditf

1、题目描述&#xff0c;下载附件&#xff0c;是一张图片 2、打开图片&#xff0c;发现宽高不一样&#xff0c;猜测可能是需要修改宽高&#xff0c;用winhex分析&#xff0c;没有发现奇怪的地方 3、用kali中的binwalk命令&#xff0c;分析图片&#xff0c;发现有个压缩包&#…

基于SpringBoot+Vue二手家电管理平台设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝1W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;还…

va_start和va_end使用介绍

一 概述 采用C语言编程的时候&#xff0c;函数中形式参数的数目通常是确定的&#xff0c;在调用时要依次给出与形式参数对应的所有实际参数。但在某些情况下希望函数的参数个数可以根据需要确定。典型的例子有大家熟悉的函数printf()、scanf()和系统调用execl()等。那么它们是怎…

基于jeecgboot-vue3的Flowable流程-待办任务(一)

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、ToDo.data.ts的数据信息如下 import {BasicColumn} from //components/Table; import {FormSchema} from //components/Table; import { rules} from //utils/helper/validator; impor…

c# iText使用

引入包 用nuget安装itext和itext.bouncy-castle-adapter包&#xff1a; 创建pdf string path "a.pdf"; PdfWriter writer new PdfWriter(path); PdfDocument pdfDoc new PdfDocument(writer); var docnew Document(pdfDoc); Paragraph p new Paragraph(&quo…

Python03:python代码初体验2

1、变量命名规范 1&#xff09;字母&#xff08;Unicode字符&#xff09;、数字、下划线&#xff0c;不能使用特殊字符&#xff0c;数字不能开头 2&#xff09;变量名是区分大小写的&#xff08;大小写敏感&#xff0c;x和X是两个不同的变量名&#xff09; 3&#xff09;不能使…

【打印功能】js简单实现表格样式的数据打印,按样式打印出来

效果图 代码部分&#xff0c;简单三步 1&#xff0c;html部分&#xff1a;写一个表格&#xff0c;然后数据填进去 <div id"printable-area" v-show"false"><div><div style"text-align: center;height: 40px;line-height: 40px;font…

语音深度鉴伪识别项目实战:基于深度学习的语音深度鉴伪识别算法模型(三)音频去噪算法大全+Python源码应用

前言 深度学习技术在当今技术市场上面尚有余力和开发空间的&#xff0c;主流落地领域主要有&#xff1a;视觉&#xff0c;听觉&#xff0c;AIGC这三大板块。 目前视觉板块的框架和主流技术在我上一篇基于Yolov7-LPRNet的动态车牌目标识别算法模型已有较为详细的解说。与AIGC相…

IDEA快捷生成左边变量,取消final关键字

一&#xff1a;问题 如图&#xff1a;每次使用CtrlALtV或.var自动生成左边变量都会有final关键字&#xff0c;然后需要删除很麻烦 二&#xff1a;解决 以下步骤设置取消生成final关键字 1.先 生成变量&#xff1a;我是使用.var自动生成左边变量 2.使用快捷键ALtshiftO或者点…

安全测试 之 安全漏洞: ClickHiJacking

1. ClickHiJacking 定义 点击劫持&#xff08;Click Jacking&#xff09;是一种视觉上的欺骗手段&#xff0c;攻击者通过使用一个透明的iframe&#xff0c;覆盖在一个网页上&#xff0c;然后诱使用户在该页面上进行操作&#xff0c;通过调整iframe页面的位置&#xff0c;可以使…

停止在你的数据库中使用UUID

在数据库中唯一标识行的最常见方法之一是使用UUID字段。然而&#xff0c;这种方法带来了需要注意的性能问题。 本文将讨论在使用UUID作为数据库表中的键时可能出现的两个性能问题。 我们直接进入正题&#xff01; 什么是UUID&#xff1f; UUID代表通用唯一标识符&#xff08;Un…

SwiftUI中ScrollViewReader的使用(自动滚动ScrollView)

ScrollViewReader是我最喜欢的SwiftUI新版本的新功能之一。在iOS 14发布之前&#xff0c;控制ScrollView的滚动位置并不容易。如果希望滚动视图滚动到特定位置&#xff0c;我们必须找到自己的解决方案。 使用ScrollViewReader&#xff0c;只需几行代码&#xff0c;就可以使滚动…