python學習之struct模塊

class struct.Struct(format)

返回一個struct對象(結構體,參考C)。python

該對象能夠根據格式化字符串的格式來讀寫二進制數據。數組

第一個參數(格式化字符串)能夠指定字節的順序。函數

默認是根據系統來肯定,也提供自定義的方式,只須要在前面加上特定字符便可:spa

struct.Struct('>I4sf')

特定字符對照表附件有。code

 

常見方法和屬性:orm

方法對象

(v1, v2, )pack

返回一個字節流對象。
blog

按照fmt(格式化字符串)的格式來打包參數v1,v2,...。內存

通俗的說就是:utf-8

首先將不一樣類型的數據對象放在一個「組」中(好比元組(1,'good',1.22)),

而後打包(「組」轉換爲字節流對象),最後再解包(將字節流對象轉換爲「組」)。

pack_into(buffer, offset, v1, v2, …)

根據格式字符串fmt包裝值v1,v2,...,並將打包的字節寫入從位置偏移開始的可寫緩衝buffer請注意,offset是必需的參數。

unpack_from(buffer, offset=0)

根據格式字符串fmt,從位置偏移開始從緩衝區解包。 結果是一個元組,即便它只包含一個項目。 緩衝區的大小(以字節爲單位,減去偏移量)必須至少爲格式所需的大小,如calcsize()所反映的。

 

屬性

format

格式化字符串。

size

結構體的大小。

 

實例:

1.一般的打包和解包

# -*- coding: utf-8 -*-
"""
打包和解包
"""
import struct
import binascii

values = (1, b'good', 1.22) #查看格式化對照表可知,字符串必須爲字節流類型。
s = struct.Struct('I4sf')
packed_data = s.pack(*values)
unpacked_data = s.unpack(packed_data)
 
print('Original values:', values)
print('Format string :', s.format)
print('Uses :', s.size, 'bytes')
print('Packed Value :', binascii.hexlify(packed_data))
print('Unpacked Type :', type(unpacked_data), ' Value:', unpacked_data)

 結果:

Original values: (1, b'good', 1.22) Format string : b'I4sf' Uses : 12 bytes Packed Value : b'01000000676f6f64f6289c3f' Unpacked Type : <class 'tuple'>  Value: (1, b'good', 1.2200000286102295) [Finished in 0.1s]

說明:

首先將數據對象放在了一個元組中,而後建立一個Struct對象,並使用pack()方法打包該元組;最後解包返回該元組。

這裏使用到了binascii.hexlify(data)函數。

binascii.hexlify(data)

返回字節流的十六進制字節流。

 

>>> a = 'hello'
>>> b = a.encode()
>>> b
b'hello'
>>> c = binascii.hexlify(b)
>>> c
b'68656c6c6f'

 

 

 

2.使用buffer來進行打包和解包

 使用一般的方式來打包和解包會形成內存的浪費,因此python提供了buffer的方式:

# -*- coding: utf-8 -*-
"""
經過buffer方式打包和解包
"""
import struct
import binascii
import ctypes

values = (1, b'good', 1.22) #查看格式化字符串可知,字符串必須爲字節流類型。
s = struct.Struct('I4sf')
buff = ctypes.create_string_buffer(s.size)
packed_data = s.pack_into(buff,0,*values)
unpacked_data = s.unpack_from(buff,0)
 
print('Original values:', values)
print('Format string :', s.format)
print('buff :', buff)
print('Packed Value :', binascii.hexlify(buff))
print('Unpacked Type :', type(unpacked_data), ' Value:', unpacked_data)

 結果:

Original values1: (1, b'good', 1.22)
Original values2: (b'hello', True)
buff : <ctypes.c_char_Array_18 object at 0x000000D5A5617348>
Packed Value : b'01000000676f6f64f6289c3f68656c6c6f01'
Unpacked Type : <class 'tuple'>  Value: (1, b'good', 1.2200000286102295)
Unpacked Type : <class 'tuple'>  Value: (b'hello', True)
[Finished in 0.1s]

說明:

針對buff對象進行打包和解包,避免了內存的浪費。

這裏使用到了函數

ctypes.create_string_buffer(init_or_size,size = None)

建立可變字符緩衝區。
返回的對象是c_char的ctypes數組。

init_or_size必須是一個整數,它指定數組的大小,或者用於初始化數組項的字節對象。

3.使用buffer方式來打包多個對象

# -*- coding: utf-8 -*-
"""
buffer方式打包和解包多個對象
"""
import struct
import binascii
import ctypes

values1 = (1, b'good', 1.22) #查看格式化字符串可知,字符串必須爲字節流類型。
values2 = (b'hello',True)
s1 = struct.Struct('I4sf')
s2 = struct.Struct('5s?')
buff = ctypes.create_string_buffer(s1.size+s2.size)
packed_data_s1 = s1.pack_into(buff,0,*values1)
packed_data_s2 = s2.pack_into(buff,s1.size,*values2)
unpacked_data_s1 = s1.unpack_from(buff,0)
unpacked_data_s2 = s2.unpack_from(buff,s1.size)
 
print('Original values1:', values1)
print('Original values2:', values2)
print('buff :', buff)
print('Packed Value :', binascii.hexlify(buff))
print('Unpacked Type :', type(unpacked_data_s1), ' Value:', unpacked_data_s1)
print('Unpacked Type :', type(unpacked_data_s2), ' Value:', unpacked_data_s2)

 結果:

Original values2: (b'hello', True) buff : <ctypes.c_char_Array_18 object at 0x000000D5A5617348> Packed Value : b'01000000676f6f64f6289c3f68656c6c6f01' Unpacked Type : <class 'tuple'>  Value: (1, b'good', 1.2200000286102295) Unpacked Type : <class 'tuple'>  Value: (b'hello', True) [Finished in 0.1s]

 

附:

1.格式化對照表

提示:

signed char(有符號位)取值範圍是 -128 到 127(有符號位)
unsigned char (無符號位)取值範圍是 0 到 255

2.字節順序,大小和校準

相關文章
相關標籤/搜索