Python之struct模块浅谈

来源:互联网 发布:淘宝网址转换微信 编辑:程序博客网 时间:2024/04/27 21:38

转载文章,查看原文

今天杯具了,来公司竟然没带鼠标,凑或用desktop touchpad吧,哎~~

  看到在进行c格式的二进制文件读取的过程中,用到了struct.unpack方法,因此开始找struct模块的一些相关解释,网上没有看到很清晰的说明,那就根据Python v2.6.5 documentation自己写一个好了。

  这个struct主要是用来处理C结构数据的,读入时先转换为Python的字符串类型,然后再转换为Python的结构化类型,比如元组(tuple)啥的~

一般输入的渠道来源于文件或者网络的二进制流。

  在转化过程中,主要用到了一个格式化字符串(format strings),用来规定转化的方法和格式。

  下面来谈谈主要的方法:

  struct.pack(fmt,v1,v2,.....)

    将v1,v2等参数的值进行一层包装,包装的方法由fmt指定。被包装的参数必须严格符合fmt。最后返回一个包装后的字符串。

  struct.unpack(fmt,string)

    顾名思义,解包。比如pack打包,然后就可以用unpack解包了。返回一个由解包数据(string)得到的一个元组(tuple),即使仅有一个数据也会被解包成        元组。其中len(string) 必须等于 calcsize(fmt),这里面涉及到了一个calcsize函数,再后面谈到。

  struct.calcsize(fmt)

    这个就是用来计算fmt格式所描述的结构的大小。

 

格式字符串(format string)由一个或多个格式字符(format characters)组成,对于这些格式字符的描述参照Python manual如下

FormatC TypePythonNotesxpad byteno value ccharstring of length 1 bsigned charinteger Bunsigned charinteger ?_Boolbool(1)hshortinteger Hunsigned shortinteger iintinteger Iunsigned intinteger or long llonginteger Lunsigned longlong qlong longlong(2)Qunsigned long longlong(2)ffloatfloat ddoublefloat schar[]string pchar[]string Pvoid *long 

说到这里,大家可能都有点迷糊了,那就看一段小代码

 

import struct # native byteorder buffer = struct.pack("ihb", 1, 2, 3) print repr(buffer) print struct.unpack("ihb", buffer) # data from a sequence, network byteorder data = [1, 2, 3] buffer = struct.pack("!ihb", *data)print repr(buffer) print struct.unpack("!ihb", buffer)

 

 

Output:

'\x01\x00\x00\x00\x02\x00\x03'
(1, 2, 3)
'\x00\x00\x00\x01\x00\x02\x03'
(1, 2, 3)

首先将参数1,2,3打包,打包前1,2,3明显属于python数据类型中的integer,pack后就变成了C结构的二进制串,转成python的string类型来显示就是  '\x01\x00\x00\x00\x02\x00\x03'。由于本机是小端('little-endian',关于大端和小端的区别请参照Google),故而高位放在低地址段。i 代表C struct中的int类型,故而本机占4位,1则表示为01000000;h 代表C struct中的short类型,占2位,故表示为0200;同理b 代表C struct中的signed char类型,占1位,故而表示为03。

其他结构的转换也类似,有些特别的可以参考Manual。

在Format string 的首位,有一个可选字符来决定大端和小端,列表如下:

CharacterByte orderSize and alignment@nativenative=nativestandard<little-endianstandard>big-endianstandard!network (= big-endian)standard

如果没有附加,默认为@,即使用本机的字符顺序(大端or小端),对于C结构的大小和内存中的对齐方式也是与本机相一致的(native),比如有的机器integer为2位而有的机器则为四位;有的机器内存对其位四位对齐,有的则是n位对齐(n未知,我也不知道多少)。

还有一个标准的选项,被描述为:如果使用标准的,则任何类型都无内存对齐。

比如刚才的小程序的后半部分,使用的format string中首位为!,即为大端模式标准对齐方式,故而输出的为'\x00\x00\x00\x01\x00\x02\x03',其中高位自己就被放在内存的高地址位了。


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 邻居把消防栓的位置占用了怎么办 查环保要停业整改一个月怎么办 抽油烟机管道公共排烟道漏烟怎么办 深圳龙华电动车被交警扣了怎么办 英国平邮寄到中国丢件怎么办 安卓app与设备不兼容怎么办 手机卡坏了收不到快递短信怎么办 pph手术后钛钉没有脱落怎么办 右侧附件囊状透明声可怎么办 刚刚出生小孩睾丸没有掉下来怎么办 汽车被依非法营运之由扣押怎么办 老婆结婚小孩两个又上夜场该怎么办 对于不断无理要求赔偿的房东怎么办 欠的钱越来越多不知道怎么办了 手机壳的开机按键不好按怎么办 对方把保权的房子卖给我怎么办 内存卡在手机上显示损坏怎么办 内存卡显示但是下载不了东西怎么办 相机sd卡没办法读卡怎么办 尼康相机新sd卡显示满了怎么办 修冰箱没几个月又坏了怎么办 星露谷物语活动中心成了仓库怎么办 你家如果油锅起火时应该怎么办 当你遇到电器起火时应该怎么办 酷派大神f2充不进去电怎么办 借车子别人开违章一年了怎么办 快递刚发货我点错了收货怎么办 快递收货地址错了已经发货了怎么办 老公在外地工地上夜班吃不好怎么办 工人在工地干活被吊车撞了怎么办 小米手机记不得保密柜密码怎么办 华为手机文件保密柜密码忘了怎么办 超市寄存柜密码纸丢了怎么办 佳明软件安装不到手机上怎么办 最好的朋友的抢了自己的活怎么办 支付宝被实名验证上限了怎么办 装修预留插座被挡了一半怎么办 衣服放在柜子里面有味道怎么办 河北发货一个柜到天津港口怎么办 家用潜水泵更换电容后压力小怎么办 无塔供水井水水位低了怎么办