1. struct二進制資料結構
struct模塊包括一些函式,這些函式可以完成位元組串與原生Python資料型別(如數字和字串)之間的轉換,
1.1 函式與Struct類
struct提供了一組處理結構值的模塊級函式,另外還有一個Struct類,格式指示符將由字串格式轉換為一種編譯表示,這與處理正則運算式的方式類似,這個轉換會耗費一些資源,所以創建一個Struct實體并在這個實體上呼叫方法時(不是使用模塊級函式)只完成一次轉換,這會更高效,下面的例子使用了Struct類,
1.2 打包和解包
Struct支持使用格式指示符將資料打包(packing)為字串,另外支持從字串解包(unpacking)資料,格式指示符由表示資料型別的字符和可選的數量及位元組序(endianness)指示符構成,
在下面的例子中,指示符要求有一個整型或長整型值、一個兩位元組字串以及一個浮點數,格式指示符中包含的空格用來分隔型別指示符,并且在編譯格式時會被忽略,
import struct import binascii values = (1, 'ab'.encode('utf-8'), 2.7) s = struct.Struct('I 2s f') packed_data = s.pack(*values) print('Original values:', values) print('Format string :', s.format) print('Uses :', s.size, 'bytes') print('Packed Value :', binascii.hexlify(packed_data))
這個例子將打包的值轉換為一個十六進制位元組序列,以便用binascii.hexlify()列印,因為有些字符是null,

使用unpack()可以從打包的表示中抽取資料,
import struct import binascii packed_data = binascii.unhexlify(b'0100000061620000cdcc2c40') s = struct.Struct('I 2s f') unpacked_data = s.unpack(packed_data) print('Unpacked Values:', unpacked_data)
將打包值傳入unpack(),基本上會得到相同的值(注意浮點值中的微小差別),

1.3 字串
默認地,值會使用原生C庫的位元組序(endianness)來編碼,只需在格式串中提供一個顯式的位元組序指令,就可以很容易地覆寫這個默認選擇,
import struct import binascii values = (1, 'ab'.encode('utf-8'), 2.7) print('Original values:', values) endianness = [ ('@', 'native, native'), ('=', 'native, standard'), ('<', 'little-endian'), ('>', 'big-endian'), ('!', 'network'), ] for code, name in endianness: s = struct.Struct(code + ' I 2s f') packed_data = s.pack(*values) print() print('Format string :', s.format, 'for', name) print('Uses :', s.size, 'bytes') print('Packed Value :', binascii.hexlify(packed_data)) print('Unpacked Value :', s.unpack(packed_data))
根據下表,格式字串的第一個字符可用于指示打包資料的位元組順序,大小和對齊方式:
|
字符 |
位元組順序 |
大小 |
對齊方式 |
|---|---|---|---|
|
|
按原位元組 |
按原位元組 |
按原位元組 |
|
|
按原位元組 |
標準 |
無 |
|
|
小端 |
標準 |
無 |
|
|
大端 |
標準 |
無 |
|
|
網路(=大端) |
標準 |
無 |

1.4 緩沖區
通常在強調性能的情況下或者向擴展模塊傳入或傳出資料時才會處理二進制打包資料,通過避免為每個打包結構分配一個新緩沖區所帶來的開銷,這些情況可以得到優化,pack_into()和unpack_from()方法支持直接寫入預分配的緩沖區,
import array import binascii import ctypes import struct s = struct.Struct('I 2s f') values = (1, 'ab'.encode('utf-8'), 2.7) print('Original:', values) print() print('ctypes string buffer') b = ctypes.create_string_buffer(s.size) print('Before :', binascii.hexlify(b.raw)) s.pack_into(b, 0, *values) print('After :', binascii.hexlify(b.raw)) print('Unpacked:', s.unpack_from(b, 0)) print() print('array') a = array.array('b', b'\0' * s.size) print('Before :', binascii.hexlify(a)) s.pack_into(a, 0, *values) print('After :', binascii.hexlify(a)) print('Unpacked:', s.unpack_from(a, 0))
Struct的size屬性指出緩沖區需要有多大,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/190367.html
標籤:Python
