Python之struct介绍及详解(与CC++通信结构体的交互)

更新时间:2023-07-19 05:13:14 阅读: 评论:0

Python之struct介绍及详解(与CC++通信结构体的交互)⽤处
1. 按照指定格式将Python数据转换为字符串,该字符串为字节流,如⽹络传输时,不能传输int,此时先将int转化为字节流,然后再发送;
2. 按照指定格式将字节流转换为Python指定的数据类型;
3. 处理⼆进制数据,如果⽤struct来处理⽂件的话,需要⽤’wb’,’rb’以⼆进制(字节流)写,读的⽅式来处理⽂件;
4. 处理c语⾔中的结构体;
struct模块中的函数
函数return explain
pack(fmt,v1,v2…)string按照给定的格式(fmt),把数据转换成字符串(字节流),并将该字符串返回.
pack_into(fmt,buffer,offt,v1,v2…)None 按照给定的格式(fmt),将数据转换成字符串(字节流),并将字节流写⼊以offt开始的buffer中.(buffer为可写的缓冲区,可⽤array模块)
unpack(fmt,v1,v2…..)tuple按照给定的格式(fmt)解析字节流,并返回解析结果
pack_from(fmt,buffer,offt)tuple按照给定的格式(fmt)解析以offt开始的缓冲区,并返回解析结果
calcsize(fmt)size of fmt计算给定的格式(fmt)占⽤多少字节的内存,注意对齐⽅式
格式化字符串
当打包或者解包的时,需要按照特定的⽅式来打包或者解包.该⽅式就是格式化字符串,它指定了数据类型,除此之外,还有⽤于控制字节顺序、⼤⼩和对齐⽅式的特殊字符.
对齐⽅式
为了同c中的结构体交换数据,还要考虑c或c++编译器使⽤了字节对齐,通常是以4个字节为单位的32位系统,故⽽struct根据本地机器字节顺序转换.可以⽤格式中的第⼀个字符来改变对齐⽅式.定义如下
Character Byte order Size Alignment
@(默认)本机本机本机,凑够4字节
=本机标准none,按原字节数
<⼩端标准none,按原字节数
>⼤端标准none,按原字节数
!network(⼤端)标准none,按原字节数
如果不懂⼤⼩端,见.
格式符
格式符C语⾔类型Python类型Standard size
x pad byte(填充字节)no value
c char string of length 11
b signed char integer1
B unsigned char integer1
_Bool bool1
h short integer2
H unsigned short integer2
i int integer4
I(⼤写的i)unsigned int integer4
l(⼩写的L)long integer4
L unsigned long long4
q long long long8
Q unsigned long long long8
f float float4
d doubl
e float8
s char[]string全马是多少公里
p char[]string
P void *long
注- -!
1. _Bool在C99中定义,如果没有这个类型,则将这个类型视为char,⼀个字节;
2. q和Q只适⽤于64位机器;
3. 每个格式前可以有⼀个数字,表⽰这个类型的个数,如s格式表⽰⼀定长度的字符串,4s表⽰长度为4的字符串;4i表⽰四个int;
4. P⽤来转换⼀个指针,其长度和计算机相关;
5. f和d的长度和计算机相关;
进制转化:
# 获取⽤户输⼊⼗进制数
dec = int(input("输⼊数字:"))
print("⼗进制数为:", dec)
print("转换为⼆进制为:", bin(dec))
print("转换为⼋进制为:", oct(dec))
print("转换为⼗六进制为:", hex(dec))
偶像英语站军姿16进制转10进制: int('0x10', 16)  ==>  16
Python没有专门处理字节的数据类型。但由于b'str'可以表⽰字节,所以,字节数组=⼆进制str。⽽在C语⾔中,我们可以很⽅便地⽤struct、union来处理字节,以及字节和int,float的转换。
在Python中,⽐⽅说要把⼀个32位⽆符号整数变成字节,也就是4个长度的bytes,你得配合位运算符这么写:
>>> n = 10240099
>>> b1 = (n & 0xff000000) >> 24
>>> b2 = (n & 0xff0000) >> 16
>>> b3 = (n & 0xff00) >> 8
>>> b4 = n & 0xff
>>> bs = bytes([b1, b2, b3, b4])
>>> bs
b'\x00\x9c@c'
⾮常⿇烦。如果换成浮点数就⽆能为⼒了。
好在Python提供了⼀个struct模块来解决bytes和其他⼆进制数据类型的转换。
pack
struct的pack函数把任意数据类型变成bytes:
>>> import struct
>>> struct.pack('>I', 10240099)
b'\x00\x9c@c'
pack的第⼀个参数是处理指令,'>I'的意思是:
>表⽰字节顺序是big-endian,也就是⽹络序,I表⽰4字节⽆符号整数。
后⾯的参数个数要和处理指令⼀致。
东台市政府
按摩教程unpack
unpack把bytes变成相应的数据类型:鱼肉
>>> struct.unpack('>IH', b'\xf0\xf0\xf0\xf0\x80\x80')
(4042322160, 32896)
根据>IH的说明,后⾯的bytes依次变为I:4字节⽆符号整数和H:2字节⽆符号整数。
所以,尽管Python不适合编写底层操作字节流的代码,但在对性能要求不⾼的地⽅,利⽤struct就⽅便多了。
struct模块定义的数据类型可以参考Python官⽅⽂档:
Windows的位图⽂件(.bmp)是⼀种⾮常简单的⽂件格式,我们来⽤struct分析⼀下。
⾸先找⼀个bmp⽂件,没有的话⽤“画图”画⼀个。
读⼊前30个字节来分析:
>>> s =
b'\x42\x4d\x38\x8c\x0a\x00\x00\x00\x00\x00\x36\x00\x00\x00\x28\x00\x00\x00\x80\x02\x00\x00\x68\x01\x00\x00\x01\x00\x18\x00'
BMP格式采⽤⼩端⽅式存储数据,⽂件头的结构按顺序如下:
两个字节:'BM'表⽰Windows位图,'BA'表⽰OS/2位图;⼀个4字节整数:表⽰位图⼤⼩;⼀个4字节整数:保留位,始终为0;⼀个4字节整数:实际图像的偏移量;⼀个4字节整数:Header的字节数;⼀个4字节整数:图像宽度;⼀个4字节整数:图像⾼度;⼀个2字节整数:始终为1;⼀个2字节整数:颜⾊数。
所以,组合起来⽤unpack读取:
>>> struct.unpack('<ccIIIIIIHH', s)
(b'B', b'M', 691256, 0, 54, 40, 640, 360, 1, 24)
结果显⽰,b'B'、b'M'说明是Windows位图,位图⼤⼩为640x360,颜⾊数为24。
请编写⼀个bmpinfo.py,可以检查任意⽂件是否是位图⽂件,如果是,打印出图⽚⼤⼩和颜⾊数。
# -*- coding: utf-8 -*-
import ba64,struct
bmp_data = ba64.b64decode('Qk1oAgAAAAAAADYAAAAoAAAAHAAAAAoAAAABABAAAAAAADICAAASCwAAEgsAAAAAAAAAAAAA/3//f/9//3//f/9//3//f/9//3//f/9//3
def bmp_info(data):
str = struct.unpack('<ccIIIIIIHH',data[:30]) #bytes类也有切⽚⽅法
if str[0]==b'B' and str[1]==b'M':
print("这是位图⽂件")
return {
'width': str[-4],
'height': str[-3],
'color': str[-1]
}
el:
print("这不是位图⽂件")
if __name__ == '__main__':
bmp_info(bmp_data)
ip地址冲突print('ok')
骨碌读音
⽰例:
现在我们有了格式字符串,也知道了封装函数,那现在先通过⼀两个例⼦看⼀看。
例⼀:⽐如有⼀个报⽂头部在C语⾔中是这样定义的
struct header
{
unsigned short  usType;
char[4]        acTag;
unsigned int    uiVersion;
unsigned int    uiLength;
};
在C语⾔对将该结构体封装到⼀块缓存中是很简单的,可以使⽤memcpy()实现。在Python中,使⽤struct就需要这样:
str = struct.pack('B4sII', 0x04, 'aaaa', 0x01, 0x0e)
'B4sII'  ------  有⼀个unsigned short、char[4], 2个unsigned int。其中s之前的数字说明了字符串的⼤⼩ 。
type, tag, version, length = struct.unpack('B4sll', str)
class struct.Struct(format)
返回⼀个struct对象(结构体,参考C)。
该对象可以根据格式化字符串的格式来读写⼆进制数据。
第⼀个参数(格式化字符串)可以指定字节的顺序。
默认是根据系统来确定,也提供⾃定义的⽅式,只需要在前⾯加上特定字符即可:

本文发布于:2023-07-19 05:13:14,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1104440.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:字节   字符串   整数   格式   进制   数据类型   转换   数据
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图