4.1.2.3フォーマット文字例


ローエンド・モードでパケットを解除し、例を割り当てます.
#python 3.4.3
import struct

record = b'raymond   \x32\x12\x08\x01\x08'
name, serialnum, school, gradelevel = struct.unpack('<10sHHb', record)
print(name, serialnum, school, gradelevel)

結果は次のように出力されます.
b'raymond   ' 4658 264 8
ここではstruct.unpackはパケットを解いて、レコードrecordバイナリストリームを分解して、4つのデータをname、serialnum、school、gradelevelの中に保存して、最後にそれらを表示します.ここで、'<10 sHHb'は、小端モード、10文字、2つの符号なし数、1つの符号付き文字タイプを表す.
 
名前付きメタグループを使用して、パケット解除されたデータの例を保存します.
#python 3.4.3
import struct
from collections import namedtuple

record = b'raymond   \x32\x12\x08\x01\x08'
name, serialnum, school, gradelevel = struct.unpack('<10sHHb', record)
print(name, serialnum, school, gradelevel)

Student = namedtuple('Student', 'name serialnum school gradelevel')
#         
print(Student._make(struct.unpack('<10sHHb', record)))

結果は次のように出力されます.
b'raymond   ' 4658 264 8
Student(name=b'raymond   ', serialnum=4658, school=264, gradelevel=8)
この例では、主にnamedtupleを使用し、直接呼び出します.makeメソッドは,解包したデータをネーミングメタグループに直接保存し,新しい変数を作成してデータを保存する必要がなく,データの構造化管理に便利である.かなりのバイナリストリームがパケットを解き,構造化されたメタグループを直接生成する.
 
デフォルトのデータ配置の例:
#python 3.4.3
import struct
 
print('ci:', struct.pack('ci', b'*', 0x12131415))
print('ic:', struct.pack('ic', 0x12131415, b'*'))
print('ci size:', struct.calcsize('ci'))
print('ic size:', struct.calcsize('ic'))
結果は次のように出力されます.
ci: b'*\x00\x00\x00\x15\x14\x13\x12'
ic: b'\x15\x14\x13\x12*'
ci size: 8
ic size: 5
この例から,同じ2つのタイプcとiのフォーマットが見られるが,配列が異なるだけで,最後にパッケージングされたバイナリストリームのサイズが異なるのは,連続する2つのタイプの間に整列文字が生じる場合である.同じホストまたは同じコンピュータで使用する場合、補足文字を追加するかどうかは同じで、異なるコンピュータでは異なる可能性があります.そのため、一般的に異なるコンピュータ間の通信には、補充しない方法で記入する必要があります.例を以下に修正します.
#python 3.4.3
import struct
 
print('=ci:', struct.pack('=ci', b'*', 0x12131415))
print('=ic:', struct.pack('=ic', 0x12131415, b'*'))
print('=ci size:', struct.calcsize('=ci'))
print('=ic size:', struct.calcsize('=ic'))
結果は次のように出力されます.
=ci: b'*\x15\x14\x13\x12'
=ic: b'\x15\x14\x13\x12*'
=ci size: 5
=ic size: 5
 
四文字で揃え、構造の後尾で揃える例:
#python 3.4.3
import struct
 
print('llh:', struct.pack('llh', 1, 2, 3))
print('llh0l:', struct.pack('llh0l', 1, 2, 3))
print('llb0l:', struct.pack('llh0l', 1, 2, 3))
結果は次のように出力されます.
llh: b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00'
llh0l: b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'
llb0l: b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'
この例では、フォーマット列の後尾にゼロ個のlを追加することで4バイトの整列を行い、ここでフォーマット文字lは数字1ではなく、ここでフォーマット文字lに注意してください.
4.1.3類struct
structモジュールでは、クラスstructを定義します.主に以下の方法があります.
class struct.Struct(format)
フォーマットformatでバイナリデータを操作できるStructオブジェクトを返します.フォーマット文字列を1回処理するだけで、異なるデータのパケット解除とパッケージングが可能になるため、このオブジェクトを使用すると、関数を使用するよりも効率的になります.
このオブジェクトは、次のメソッドとプロパティをサポートします.
pack(v1, v2, ...) 
pack()関数機能と同様に、コンパイルされたフォーマット文字列でパッケージ化されます.
 
pack_into(buffer, offset, v1, v2, ...) 
pack_とinto()関数機能と同様に、コンパイルされたフォーマット文字列でパッケージ化されます.
 
unpack(buffer) 
unpack()関数機能と同様に,コンパイルされたフォーマット文字列でパケットを解く.
 
unpack_from(buffer, offset=0) 
とunpack_from()関数機能と同様に,コンパイルされたフォーマット文字列でパケットを解く.
 
iter_unpack(buffer) 
とiter_unpack()関数機能と同様に,コンパイルされたフォーマット文字列でパケットを解く.
 
format 
構築時に入力されたフォーマット文字列を保存します.
 
size 
フォーマット文字列に基づいて計算するには、バイナリバッファのサイズが必要です.
例:
#python 3.4.3
import struct
 
fmt = struct.Struct('llh')
print(fmt.format)
print(fmt.size)
 
encode = fmt.pack(1, 2, 3)
print(encode)
print(fmt.unpack(encode))
結果は次のように出力されます.
b'llh'
10
b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00'
(1, 2, 3)
蔡軍生QQ:9073204深セン