class struct.Struct(format)

返回一个struct对象(结构体,参考C)。

该对象可以根据格式化字符串的格式来读写二进制数据。

第一个参数(格式化字符串)可以指定字节的顺序。

默认是根据系统来确定,也提供自定义的方式,只需要在前面加上特定字符即可:

struct.Struct('>I4sf')

特定字符对照表附件有。

常见方法和属性:

方法

pack(v1, v2, )

返回一个字节流对象。

按照fmt(格式化字符串)的格式来打包参数v1,v2,...。

通俗的说就是:

首先将不同类型的数据对象放在一个“组”中(比如元组(1,'good',1.22)),

然后打包(“组”转换为字节流对象),最后再解包(将字节流对象转换为“组”)。

pack_into(buffer, offset, v1, v2, …)

根据格式字符串fmt包装值v1,v2,...,并将打包的字节写入从位置偏移开始的可写缓冲buffer。 请注意,offset是必需的参数。

unpack_from(buffer, offset=)

根据格式字符串fmt,从位置偏移开始从缓冲区解包。 结果是一个元组,即使它只包含一个项目。 缓冲区的大小(以字节为单位,减去偏移量)必须至少为格式所需的大小,如calcsize()所反映的。

属性

format

格式化字符串。

size

结构体的大小。

实例:

1.通常的打包和解包

# -*- coding: utf-8 -*-
"""
打包和解包
"""
import struct
import binascii values = (1, b'good', 1.22) #查看格式化对照表可知,字符串必须为字节流类型。
s = struct.Struct('I4sf')
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: (, b'good', 1.22)
Format string : b'I4sf'
Uses : bytes
Packed Value : b'01000000676f6f64f6289c3f'
Unpacked Type : <class 'tuple'> Value: (, b'good', 1.2200000286102295)
[Finished in .1s]

说明:

首先将数据对象放在了一个元组中,然后创建一个Struct对象,并使用pack()方法打包该元组;最后解包返回该元组。

这里使用到了binascii.hexlify(data)函数。

binascii.hexlify(data)

返回字节流的十六进制字节流。

>>> a = 'hello'
>>> b = a.encode()
>>> b
b'hello'
>>> c = binascii.hexlify(b)
>>> c
b'68656c6c6f'

2.使用buffer来进行打包和解包

使用通常的方式来打包和解包会造成内存的浪费,所以python提供了buffer的方式:

# -*- coding: utf-8 -*-
"""
通过buffer方式打包和解包
"""
import struct
import binascii
import ctypes values = (1, b'good', 1.22) #查看格式化字符串可知,字符串必须为字节流类型。
s = struct.Struct('I4sf')
buff = ctypes.create_string_buffer(s.size)
packed_data = s.pack_into(buff,0,*values)
unpacked_data = s.unpack_from(buff,0) print('Original values:', values)
print('Format string :', s.format)
print('buff :', buff)
print('Packed Value :', binascii.hexlify(buff))
print('Unpacked Type :', type(unpacked_data), ' Value:', unpacked_data)

结果:

Original values1: (1, b'good', 1.22)
Original values2: (b'hello', True)
buff : <ctypes.c_char_Array_18 object at 0x000000D5A5617348>
Packed Value : b'01000000676f6f64f6289c3f68656c6c6f01'
Unpacked Type : <class 'tuple'>  Value: (1, b'good', 1.2200000286102295)
Unpacked Type : <class 'tuple'>  Value: (b'hello', True)
[Finished in 0.1s]

说明:

针对buff对象进行打包和解包,避免了内存的浪费。

这里使用到了函数

ctypes.create_string_buffer(init_or_size,size = None)

创建可变字符缓冲区。
返回的对象是c_char的ctypes数组。

init_or_size必须是一个整数,它指定数组的大小,或者用于初始化数组项的字节对象。

3.使用buffer方式来打包多个对象

# -*- coding: utf-8 -*-
"""
buffer方式打包和解包多个对象
"""
import struct
import binascii
import ctypes values1 = (1, b'good', 1.22) #查看格式化字符串可知,字符串必须为字节流类型。
values2 = (b'hello',True)
s1 = struct.Struct('I4sf')
s2 = struct.Struct('5s?')
buff = ctypes.create_string_buffer(s1.size+s2.size)
packed_data_s1 = s1.pack_into(buff,0,*values1)
packed_data_s2 = s2.pack_into(buff,s1.size,*values2)
unpacked_data_s1 = s1.unpack_from(buff,0)
unpacked_data_s2 = s2.unpack_from(buff,s1.size) print('Original values1:', values1)
print('Original values2:', values2)
print('buff :', buff)
print('Packed Value :', binascii.hexlify(buff))
print('Unpacked Type :', type(unpacked_data_s1), ' Value:', unpacked_data_s1)
print('Unpacked Type :', type(unpacked_data_s2), ' Value:', unpacked_data_s2)

结果:

Original values2: (b'hello', True)
buff : <ctypes.c_char_Array_18 object at 0x000000D5A5617348>
Packed Value : b'01000000676f6f64f6289c3f68656c6c6f01'
Unpacked Type : <class 'tuple'> Value: (, b'good', 1.2200000286102295)
Unpacked Type : <class 'tuple'> Value: (b'hello', True)
[Finished in .1s]

附:

1.格式化对照表

提示:

signed char(有符号位)取值范围是 -128 到 127(有符号位)
unsigned char (无符号位)取值范围是 0 到 255

2.字节顺序,大小和校准

python学习之struct模块的更多相关文章

  1. 浅析Python中的struct模块

    最近在学习python网络编程这一块,在写简单的socket通信代码时,遇到了struct这个模块的使用,当时不太清楚这到底有和作用,后来查阅了相关资料大概了解了,在这里做一下简单的总结. 了解c语言 ...

  2. 【转】浅析Python中的struct模块

    [转]浅析Python中的struct模块 最近在学习python网络编程这一块,在写简单的socket通信代码时,遇到了struct这个模块的使用,当时不太清楚这到底有和作用,后来查阅了相关资料大概 ...

  3. Python学习 Part4:模块

    Python学习 Part4:模块 1. 模块是将定义保存在一个文件中的方法,然后在脚本中或解释器的交互实例中使用.模块中的定义可以被导入到其他模块或者main模块. 模块就是一个包含Python定义 ...

  4. python学习之argparse模块

    python学习之argparse模块 一.简介: argparse是python用于解析命令行参数和选项的标准模块,用于代替已经过时的optparse模块.argparse模块的作用是用于解析命令行 ...

  5. Python学习day19-常用模块之re模块

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  6. Python学习day18-常用模块之NumPy

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  7. python中的struct模块的学习

    由于TCP协议中的黏包现象的发生,对于最low的办法,每次发送之前让他睡一秒,然后在发送,可是这样真的太low了,而且太占用资源了. 黏包现象只发生在tcp协议中: 1.从表面上看,黏包问题主要是因为 ...

  8. Python学习笔记-常用模块

    1.python模块 如果你退出 Python 解释器并重新进入,你做的任何定义(变量和方法)都会丢失.因此,如果你想要编写一些更大的程序,为准备解释器输入使用一个文本编辑器会更好,并以那个文件替代作 ...

  9. python学习之random模块

    Python中的random模块用于生成随机数.下面介绍一下random模块中最常用的几个函数. random.random random.random()用于生成一个0到1的随机符点数: 0 < ...

随机推荐

  1. simple简单消息队列

    一:介绍 1.优缺点 简单,但是耦合性较高. 这种模式是生产者与消费者一一对应,就是一个产生者,有一个消费者来消费. 如果,多个消费者想消费一个队列中的消息就不适合了.这种情况在后面会接着介绍. 2. ...

  2. Unity 之 场景切换

      Application.LoadLevel();//场景名称或索引,删除掉原场景的所有东西 Application.LoadLevelAdditive()//添加并加载场景,不删除当前场景的物体, ...

  3. django基类View.as_view()

    参考:https://www.zmrenwu.com/post/53/ 详细见参考 一般请求的判断方法: def view(request, *args, **kwargs): if request. ...

  4. laravel5 项目上线后务必将开发环境更改为生产环境

    如果以开发环境上线,出错信息将全通过json暴露出来了,屏蔽方式如下: .env 文件设置如下APP_ENV=productionAPP_DEBUG=false 改完设置后把缓存清理一遍 如果更改后清 ...

  5. SpringMvc @ResponseBody

    一.@Response使用条件 二. @Response在最小配置.jackson的jar包情况下,json中包含的日期类型字段都是以时间戳long类型返回 三. Jack序列化对象转为JSON的限制 ...

  6. flask源码剖析

    这段时间想重新写个自己的博客系统,又正好在看一些框架源码,然后就想要不顺便写个小框架吧,既然想写框架,要不再顺便写个orm吧,再写个小的异步Server吧..事实证明饭要一口一口吃 先梳理一下flas ...

  7. BZOJ.4892.[TJOI2017]DNA(后缀自动机/后缀数组)

    题目链接 \(Description\) 给出两个串\(S,T\),求\(T\)在\(S\)中出现了多少次.出现是指.可以有\(3\)次(\(3\)个字符)不匹配(修改使其匹配). \(Solutio ...

  8. BZOJ.1875.[SDOI2009]HH去散步(DP 矩阵乘法)

    题目链接 比较容易想到用f[i][j]表示走了i步后到达j点的方案数,但是题目要求不能走上一条走过的边 如果这样表示是不好转移的 可以考虑边,f[i][j]表示走了i步后到达第j条边的方案数,那么有 ...

  9. 线性代数与Python

    1.向量1.1向量例子1.2向量加法与减法1.3向量的乘法2.矩阵2.1矩阵例子2.2矩阵的形状2.3矩阵的创建函数 1.向量 向量是指可以加总(以生成新的向量),可以乘以标量(即数字),也可以生成新 ...

  10. [SNOI2017]一个简单的询问

    [SNOI2017]一个简单的询问 题目大意: 给定一个长度为\(n(n\le50000)\)的序列\(A(1\le A_i\le n)\),定义\(\operatorname{get}(l,r,x) ...