struct模块用于二进制和结构体之间的互相转化,此模块中大部分函数接受一个实现了Buffer协议的对象,最常见的实现了Buffer协议的对象包括bytes、bytearray等,大多数像byte数组这样的对象都实现了Buffer协议。

struct模块的函数

struct模块的函数很少,只有6个。

struct.pack(format, v1, v2, ...):将多个value如v1、v2按照format进行格式化

struct.pack_into(format, buffer, offset, v1, v2, ...):将多个value如v1、v2按照format格式化到buffer的offset处

struct.unpack(format, buffer):从buffer中按照format解析对象

struct.unpack_from(format, buffer, offset=0):从buffer的某个offset处解析对象

struct.iter_unpack(format, buffer):以迭代的形式从buffer中解析对象

struct.calcsize(format):返回format所指定的数据类型的字节数

从以上函数看出,struct模块中格式化字符串format非常重要,format包括两部分:控制部分、类型部分。

以Struct的形式调用struct包的能

struct包提供了Struct类,这个类的构造函数接受一个format串,从而可以使用对象的函数了,可以避免传format参数。

msgpack中的Packer和Unpacker也是类似的作用。

举例

demo1:将int转换为bytes

buf1 = 256
bin_buf1 = struct.pack('i', buf1) # 'i'代表'integer'
ret1 = struct.unpack('i', bin_buf1)
print(bin_buf1, ' <====> ', ret1)

这段程序将256这个数字通过pack函数转化成了bytes类型,其中pack的第一个参数i表示buf1为int类型的数据。

demo2:将浮点数转化为bytes

buf2 = 3.1415
bin_buf2 = struct.pack('d', buf2) # 'd'代表'double'
ret2 = struct.unpack('d', bin_buf2)
print(bin_buf2, ' <====> ', ret2)

demo3:将字符串转换为bytes

# 字符串 -> 二进制流
buf3 = 'Hello World'
bin_buf3 = struct.pack('11s', bytes(buf3,encoding='ascii')) # '11s'代表长度为11的'string'字符数组
ret3 = struct.unpack('11s', bin_buf3)
print(bin_buf3, ' <====> ', ret3)

这里的11s表示buf3为长度11个字符的数组。同理,也可以使用“11i”表示11个int类型的数据,还可以使用“iiiiiiiiiii”表示11i

demo4:将结构体转化为bytes

# 结构体 -> 二进制流
# 假设有一个结构体
# struct header {
# int buf1;
# double buf2;
# char buf3[11];
# }
bin_buf_all = struct.pack('id11s', buf1, buf2, bytes(buf3,encoding='ascii'))
ret_all = struct.unpack('id11s', bin_buf_all)
print(bin_buf_all, ' <====> ', ret_all)

demo5:常用方法

# 按照给定的格式化字符串,把数据封装成字符串(实际上是类似于c结构体的字节流)
string = struct.pack(fmt, v1, v2, ...) # 按照给定的格式(fmt)解析字节流string,返回解析出来的tuple
tuple = unpack(fmt, string) # 计算给定的格式(fmt)占用多少字节的内存
offset = calcsize(fmt)

手册

格式化字符串的存储部分

从表中可以发现如下规律:

  • 整数类型b、h、i、q分别表示1个字节、2个字节、4个字节、8个字节,对应的大写字母表示无符号整数
  • f、d表示float和double
  • c表示字符、s表示字符串,需要注意:struct模块并不能直接将str类型转为bytes,当format为c和s时,对象需要是byte类型或者bytes类型
Format C Type Python 字节数
x pad byte no value 1
c char string of length 1 1
b signed char integer 1
B unsigned char integer 1
? _Bool bool 1
h short integer 2
H unsigned short integer 2
i int integer 4
I unsigned int integer or lon 4
l long integer 4
L unsigned long long 4
q long long long 8
Q unsigned long long long 8
f float float 4
d double float 8
s char[] string 1
p char[] string 1
P void * long

格式化字符串的控制部分

  • @表示默认,一切以本地为主
  • =表示对象的大小使用标准大小
  • <>表示小头序和大头序
  • 永远不会用到,可以忽略
Character Byte order Size and alignment
@ native native 凑够4个字节
= native standard 按原字节数
< little-endian standard 按原字节数
> big-endian standard 按原字节数
! network (= big-endian) standard 按原字节数

#参考资料
[monitor1379](http://www.jianshu.com/p/5a985f29fa81)

python中的struct模块的更多相关文章

  1. 浅析Python中的struct模块

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

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

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

  3. python中的struct模块的学习

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

  4. Python中的random模块,来自于Capricorn的实验室

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

  5. Python中的logging模块

    http://python.jobbole.com/86887/ 最近修改了项目里的logging相关功能,用到了python标准库里的logging模块,在此做一些记录.主要是从官方文档和stack ...

  6. Python中的random模块

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

  7. python中的StringIO模块

    python中的StringIO模块 标签:python StringIO 此模块主要用于在内存缓冲区中读写数据.模块是用类编写的,只有一个StringIO类,所以它的可用方法都在类中.此类中的大部分 ...

  8. python中的select模块

    介绍: Python中的select模块专注于I/O多路复用,提供了select  poll  epoll三个方法(其中后两个在Linux中可用,windows仅支持select),另外也提供了kqu ...

  9. Python中的re模块--正则表达式

    Python中的re模块--正则表达式 使用match从字符串开头匹配 以匹配国内手机号为例,通常手机号为11位,以1开头.大概是这样13509094747,(这个号码是我随便写的,请不要拨打),我们 ...

随机推荐

  1. 为什么static数据成员一定要在类外初始化?(转)

    1.避免重复定义和初始化 <<c++ primer>>说在类外定义和初始化是保证static成员变量只被定义一次的好方法. 但,为什么static const int就可以在类 ...

  2. bash: php: command not found

    bash: php: command not found 解决:export PATH=$PATH:/usr/local/php/bin

  3. paypal 的IPN通知调用出错

    一直报错: 当本地curl需要访问https时,出现SSL certificate: unable to get local issuer certificate错误信息 解决办法: 到http:// ...

  4. windows 查看动态连接库和静态连接库的方法

    在window下查看动态库的导出函数可以用vs自带的Dependenc工具: 查看静态库的信息要用命令行来实现: dumpbin   /LINKERMEMBER   Test.lib   >   ...

  5. RateLimiter 限流

    @RestControllerpublic class RateLimiterController { private RateLimiter rateLimiter = RateLimiter.cr ...

  6. NSProxy

    NSProxy类在分布式对象架构中是很重要的.由于作用比较特别,NSProxy在Cocoa程序中出现频率很低. NSProxy 是一个抽象类,它为一些表现的像是其它对象替身或者并不存在的对象定义一套A ...

  7. Mockito单测,mock service层的mapper

    转载:https://blog.csdn.net/paincupid/article/details/53561435 1.引入mockito jar包 <dependency> < ...

  8. CAD2006您没有足够的权限来安装本产品

    在Win10的环境下安装CAD2006,可能会报错"您没有足够的权限来安装本产品". 解决方法是,右键以"兼容性疑难解答"运行 在弹出的对话框中,点击 &quo ...

  9. SDE注册版本失败,仅支持一个空间列

    如果直接编辑SDE要素类与要素可以不需要版本,使用默认版本,如果要让用户通过界面编辑,即使用开启编辑.保存编辑和停止编辑,就需要注册为版本,而在注册版本弹出如下错误: 正如错误所说,一个要素类或shp ...

  10. docker安装tomcat

    先在官网上找可用的镜像 我使用的是7-jre8 获取tomcat镜像的命令:$docker pull tomcat:7-jre8 获取完镜像以后,通过命令可以列举出已有的镜像: 列举镜像的命令:$do ...