python struct 用法_Python标准库笔记struct模块的使用

news/2025/2/23 22:11:17

最近在学习python网络编程这一块,在写简单的socket通信代码时,遇到了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模块提供了很简单的几个函数,下面写几个例子。

该模块作用是完成Python数值和C语言结构体的Python字符串形式间的转换。这可以用于处理存储在文件中或从网络连接中存储的二进制数据,以及其他数据源。

用途: 在Python基本数据类型和二进制数据之间进行转换

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

模块函数和Struct类

它除了提供一个Struct类之外,还有许多模块级的函数用于处理结构化的值。这里有个格式符(Format specifiers)的概念,是指从字符串格式转换为已编译的表示形式,类似于正则表达式的处理方式。通常实例化Struct类,调用类方法来完成转换,比直接调用模块函数有效的多。下面的例子都是使用Struct类。

Packing(打包)和Unpacking(解包)

Struct支持将数据packing(打包)成字符串,并能从字符串中逆向unpacking(解压)出数据。

在本例中,格式指定器(specifier)需要一个整型或长整型,一个两个字节的string,和一个浮点数。格式符中的空格用于分隔各个指示器(indicators),在编译格式时会被忽略。

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))

# 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(),基本上返回相同的值(浮点数会有差异)。

字节顺序/大小/对齐

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

Character

Byte order

Size

Alignment

@

本地

本地

本地

=

本地

standard

none

<

little-endian(小字节序)

standard

none

>

big-endian(大字节序)

standard

none

!

network (= big-endian)

standard

none

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

本地字节顺序是指字节顺序是由当前主机系统决定。比如: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'),

('

('>', '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)

格式符

格式符对照表如下:

Format

C Type

Python type

Standard size

Notes

x

pad byte

no value

c

char

bytes of length 1

1

b

signed char

integer

1

(1),(3)

B

unsigned char

integer

1

(3)

?

_Bool

bool

1

(1)

h

short

integer

2

(3)

H

unsigned short

integer

2

(3)

i

int

integer

4

(3)

I

unsigned int

integer

4

(3)

l

long

integer

4

(3)

L

unsigned long

integer

4

(3)

q

long long

integer

8

(2), (3)

Q

unsigned long long

integer

8

(2), (3)

n

ssize_t

integer

(4)

N

size_t

integer

(4)

f

float

float

4

(5)

d

double

float

8

(5)

s

char[]

bytes

p

char[]

bytes

P

void *

integer

(6)

缓冲区

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

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

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

import array

import binascii

import ctypes

import struct

s = struct.Struct('I 2s f')

values = (1, 'ab'.encode('utf-8'), 2.7)

print('原始值:', values)

print()

print('使用ctypes模块string buffer')

b = ctypes.create_string_buffer(s.size)

print('原始buffer :', binascii.hexlify(b.raw))

s.pack_into(b, 0, *values)

print('打包结果写入 :', binascii.hexlify(b.raw))

print('解包 :', s.unpack_from(b, 0))

print()

print('使用array模块')

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))

# output

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

使用ctypes模块string buffer

原始buffer  : b'000000000000000000000000'

打包结果写入 : b'0100000061620000cdcc2c40'

解包        : (1, b'ab', 2.700000047683716)

使用array模块

原始值   : b'000000000000000000000000'

打包写入 : b'0100000061620000cdcc2c40'

解包     : (1, b'ab', 2.700000047683716)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。


http://www.niftyadmin.cn/n/712370.html

相关文章

从人机大战看智能安防三大趋势

安防三大智能化趋势 在安防智能化进程中&#xff0c;实际上要解决三个问题&#xff1a;数据结构化、业务智能化、应用大数据化。总的来说就是三大智能化趋势&#xff1a;结构化的智能、业务的智能、大数据的智能。 由于安防本身业务应用的需求决定了安防人工智能市场的潜在需求…

java建立二叉查找树_Java创建二叉搜索树,实现搜索,插入,删除的操作实例

Java实现的二叉搜索树&#xff0c;并实现对该树的搜索&#xff0c;插入&#xff0c;删除操作(合并删除&#xff0c;复制删除)首先我们要有一个编码的思路&#xff0c;大致如下&#xff1a;1、查找&#xff1a;根据二叉搜索树的数据特点&#xff0c;我们可以根据节点的值得比较来…

Python笔记_第四篇_高阶编程_实例化方法、静态方法、类方法和属性方法概念的解析。...

1.先叙述静态方法&#xff1a; 我们知道Python调用类的方法的时候都要进行一个实例化的处理。在面向对象中&#xff0c;一把存在静态类&#xff0c;静态方法&#xff0c;动态类、动态方法等乱七八糟的这么一些叫法。其实这些东西看起来抽象&#xff0c;但是很好理解。这里面有一…

web前端学习(九)——HTML5区块与布局的相关标签设置

1.HTML5中区块的设置 大多数 HTML 元素被定义为块级元素或内联元素。 块级元素在浏览器显示时&#xff0c;通常会以新行来开始&#xff08;和结束&#xff09;。 实例&#xff1a;<h1>&#xff0c;<p>&#xff0c;<ul>&#xff0c;<table>。 内联元素在…

Linux下安装LoadRunner(LoadGenerator)

1. 在HP的官方网站上下载LoadRunner9.5 的Linux安装程序[T7177-15009.iso]&#xff0c;安装文档[hp_man_LRIG9.50_01_pdf.pdf]&#xff1b; 安装程序包括Hp、Ibm、Linux、Solaris系统的支持&#xff08;LR9.0对应安装文件为[TLRNUX900WC_00.zip]&#xff09;。 2. 安…

java web应用目录结构_java web应用目录结构

java web应用目录结构(2014-08-29 23:22:09)标签&#xff1a;根目录web应用程序目录文件存放处分类&#xff1a;JSP应用程序目录&#xff1a;Web应用程序的根目录。如图所示的根目录myWebApp。Web应用程序的文件组织结构/WEB-INF目录&#xff1a;Web应用应用部署目录&#xff0…

BeanFactory和ApplicationContext的区别+部分Spring的使用

BeanFactory和ApplicationContext的区别 ApplicationContext 方式加载&#xff1a;创建容器的同时 容器初始化&#xff0c;容器所有的bean创建完毕 Spring容器中获取一个对象 通过类型直接获取 BeanFactory 方式加载&#xff1a;创建容器对象&#xff0c;BeanFactory当调用getB…

爱盛科技于中国电子展演示穿戴式装置地磁传感器方案

2016年11 月8日&#xff0c;以“信息化带动工业化&#xff0c;电子技术促进产业升级”为主题&#xff0c;由中国电子器材总公司主办&#xff0c;中电会展与信息传播有限公司承办的第88届中国电子展联手IC China 2016及2016上海亚洲电子展&#xff0c;在上海新国际博览中心隆重开…