最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

Python中struct 模块的使用教程

来源:博客园


(资料图片)

1.struct 简单介绍

struct 是 Python 的内置模块, 在使用 socket 通信的时候, 大多数据的传输都是以二进制流的形式的存在, 而 struct 模块就提供了一种机制, 该机制可以将某些特定的结构体类型打包成二进制流的字符串然后再网络传输,而接收端也应该可以通过某种机制进行解包还原出原始的结构体数据

2.struct 的使用

struct 模块可以将任意大小的数字转换成一个固定长度(可选择)的 bytes, 这个原理类似于前面章节讲过的 hash 算法, 不论内容多大, 最终的 hash 值长度不变, 不同的是 hash 算法是不可逆的, 而且传入的原材料可以是文本、字符串等许多数据类型, struct 可以反解出原来的数据

ps : struct 模块只能转换数字, 不能转换其他的数据类型

3.基本使用 pack 和 unpack

正确使用示例 (打包字节长度对应表请往下看)

import structres = struct.pack("i",1234566)  # 传入的必须是 int 类型print(res)          # b"\x86\xd6\x12\x00"  (查看内容)print(type(res))    #       (查看类型)res2 = struct.unpack("i",res)   # 使用什么 Format 打包就用什么解包print(res2)         # (1234566,)           (是个元组)print(type(res2))   #       (查看类型)print(res2[0])      # 1234566         

传入非 int 类型引发的错误示例

import structres = struct.pack("i","1231")# 抛出异常 : struct.error: required argument is not an integer (参数必须是整数)

解包时使用的 Format 不一致错误示例

import structres = struct.pack("i",123)res2 = struct.unpack("q",res)# struct.error: unpack requires a buffer of 8 bytes

传入多个值

res = struct.pack("hiq",12,23,451312)  # 传入多个值, 并使用不同的 Fromatprint(res)  # b"\x0c\x00\x00\x00\x17\x00\x00\x00\xf0\xe2\x06\x00\x00\x00\x00\x00"print(type(res))  # a,b,c = struct.unpack("hiq",res)  # 使用解压赋值,有几个值就需要有几个 Fromatprint(a,b,c)                      # 12 23 451312

Fromat 与值不一致错误示例

with open("aaa.txt","wb")as f:    for i in range(5):        res = struct.pack("i",i)        f.write(res)        with open("aaa.txt","rb")as f:    res = f.read()    print(res)    a,b,c,d,e= struct.unpack("i",res)  # 打包的时候是 5 个值, 解包的时候也要传 5 个值    print(a,b,c,d,e)  # 抛出异常 : struct.error: unpack requires a buffer of 4 bytes

打包一个 json 后的信息长度, 在 socket 中可用于发送报头(报头为固定长度)

import structimport jsondic = {    "header_name" : "a.txt",    "total_size" : 22,    "heash" : "shawn"} #Python小白学习交流群:725638078res = json.dumps(dic)  # 将报头序列化lens = struct.pack("i",len(res))  # 将报头的长度传入并打包lens2 = struct.unpack("i",lens)   # 假设通信另一端收到打包的二进制,再进行解包拿到长度print(lens2)    # (60,)print(lens[0])  # 60

4.打包字节长度对照表

字符(Format)cTypePython typeStandard size
xpad byteno value
ccharstring of length 11
bsigned charinteger1
Bunsigned charinteger1
?_Boolbool1
hshortinteger2
Hunsigned shortinteger2
iintinteger4
I(大写i)unsigned intinteger4
l(小写L)longinteger4
Lunsigned longinteger4
qlong longinteger8
Qunsigned long longinteger8
ffloatfloat4
ddoublefloat8
scharlstring
pcharlstring
Pvoid*integer

关键词: