4. 二进制数据处理库

二进制处理库主要是针对二进制数据的操作和使用,也有介绍一些特定的操作,比如像文件格式和网络协议。

在前面也介绍了文本处理库,其实有一部分功能也是能处理二进制数据的,比如正则表达式re,或者是difflib比较库对数据进行处理。此外,在python内部也提供了bytes/bytearray/memoryview等数据类型进行操作。

4.1 struct--二进制数据打包和解包

本模块主要对python的数值与C结构表示为pythonbytes对象之间进行转换。通过此模块可以处理以二进制保存在文件里的数据,也可以处理网络连接之间相互传送的数据,或者其它来源的二进制数据。此模拟主要通过格式化字符串方式来描述C结构的保存格式,然后根据这个格式来读取或保存python内部表示的数据类型。

在模块struct里,很多函数都需要使用一个缓冲区参数,因而此缓冲区参数应实现buffer协议,并且提供读或者读写的功能。大多数情况下使用bytesbytearray都可以满足要求,不过其它类型也有实现buffer协议,基本上都是可以查看的功能。

4.1.1 函数和异常

本模块定义下面异常和函数功能:

exception struct.error

定义struct操作出错异常原因,struct.error是返回一个字符串描述出错原因。

例子:

#python 3.4.3

import struct

 

b = 0

 

try:

    print('测试')

    struct.pack('a', b)

except struct.error as error:

    print('异常出错提示:', error)

结果输出如下:

测试

异常出错提示: bad char in struct format

 

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

把参数v1v2按格式fmt格式化填充到缓冲区,返回一个bytes对象。参数的个数和类型要与格式化字符串一致。

例子:

#python 3.4.3

import struct

 

print(struct.pack('hhl', 1, 2, 3))

结果输出如下:

b'\x01\x00\x02\x00\x03\x00\x00\x00'

 

struct.pack_into(fmt, buffer, offset, v1, v2, ...) 

把参数v1v2按格式fmt打包,并写入缓冲区对象buffer的开始位置offset处。注意位置参数offset一定要提供。

例子:

#python 3.4.3

import struct

 

buf = bytearray(10)

print(struct.pack_into('hhl', buf, 0, 1, 2, 3))

print(buf)

结果输出如下:

None

bytearray(b'\x01\x00\x02\x00\x03\x00\x00\x00\x00\x00')

 

struct.unpack(fmt, buffer) 

从一个缓冲区bytes对象buffer按格式化字符串进行解包,把解包出来的相应字段生成一个元组返回。缓冲区的大小应满足len(bytes)等于calcsize(fmt)大小。否则会抛出异常错误。

例子:

#python 3.4.3

import struct

 

buf = struct.pack('hhl', 1, 2, 3)

print(buf)

 

print(struct.unpack('hhl', buf))

结果输出如下:

b'\x01\x00\x02\x00\x03\x00\x00\x00'

(1, 2, 3)

 

struct.unpack_from(fmt, buffer, offset=0) 

从缓冲区buffer的指定位置offset,按格式fmt进行解包,把结果放到元组里。要求buffer[offset:]的大小至少大于calcsize(fmt)的大小。

例子:

#python 3.4.3

import struct

 

buf = bytearray(10)

struct.pack_into('hhl', buf, 0, 1, 2, 3)

print(buf)

 

tmp = struct.unpack_from('hhl', buf, 0)

print(tmp)

结果输出如下:

bytearray(b'\x01\x00\x02\x00\x03\x00\x00\x00\x00\x00')

(1, 2, 3)

 

struct.iter_unpack(fmt, buffer)

迭代地按格式fmt来解包缓冲区buffer,要求buffer的长度刚好是格式fmt的整数倍大小,否则抛出异常。与unpack()多次调用比较主要是提高解包的速度。

例子:

#python 3.4.3

import struct

 

buf = bytearray(20)

struct.pack_into('hhl', buf, 0, 1, 2, 3)

struct.pack_into('hhl', buf, 8, 4, 5, 6)

print(buf)

 

btBuf = bytes(buf[0:16])

for tmp in struct.iter_unpack('hhl', btBuf):

    print(tmp)

结果输出如下:

bytearray(b'\x01\x00\x02\x00\x03\x00\x00\x00\x04\x00\x05\x00\x06\x00\x00\x00\x00\x00\x00\x00')

(1, 2, 3)

(4, 5, 6)

 

struct.calcsize(fmt) 

计算给出格式字符串fmt来计算需要缓冲区的大小。

例子:

#python 3.4.3

import struct

 

print('hhl:', struct.calcsize('hhl'))

print('hhh:', struct.calcsize('hhh'))

结果输出如下:

hhl: 8

hhh: 6


蔡军生 QQ:9073204 深圳

你可能感兴趣的:(python,二进制,网络协议,milang)