logo

Pythonの構造体モジュール

構造体モジュール パイソン Python 値と C スタイルのバイナリ データの間で変換する機能を提供することで、バイナリ データを操作できるようになります。これは、バイナリ ファイル形式やネットワーク プロトコルを扱う場合に特に便利です。その主な機能は次のとおりです。

  • パッキング Python 値をバイナリ データ (バイト) に変換します。
  • 開梱 バイナリデータを Python 値に変換し直します。
  • フォーマット文字列 形式コードを使用してデータがどのようにパック/アンパックされるかを定義します (例: 整数の場合は i、浮動小数点数の場合は f)。

struct.pack() のメソッド

1.Struct.pack(): Python 値をパックされたバイナリ形式に変換します。フォーマット文字列 (fmt) はパックされたデータのレイアウトを指定し、後続の値 (v1 v2 ...) はこのフォーマットに従ってパックされます。 構文:

struct.pack(fmt v1 v2 ...)



  • : データのパック方法を指定するフォーマット文字列。
  • v1 v2 ...: 指定された形式に従ってパックされる値。
Python
import struct # pack values into binary var = struct.pack('hhl' 1 2 3) print(var) var = struct.pack('iii' 1 2 3) print(var) 

出力
b'x01x00x02x00x00x00x00x00x03x00x00x00x00x00x00x00' b'x01x00x00x00x02x00x00x00x03x00x00x00' 

説明: 「hhl」 2 つの短整数 (h それぞれ 2 バイト) とその後に長整数 (l はプラットフォームに応じて通常 4 または 8 バイト) が続くことを意味します。 「iii」 3 つの 4 バイト整数をパックします。出力はバイト (b'') 単位で、値のバイナリ エンコーディングを表します。

2.struct.unpack(): パックされたバイナリ データを Python 値に変換します。フォーマット文字列 (fmt) とパックされたバイナリ文字列を受け取り、アンパックされた値のタプルを返します。 構文:

struct.unpack(fmt 文字列)

Javaスタック
  • FM: データを解凍する方法を指定するフォーマット文字列。
  • 弦: 解凍する必要があるパックされたバイナリ データ。
Python
import struct var = struct.pack('?hil' True 2 5 445) print(var) tup = struct.unpack('?hil' var) print(tup) var = struct.pack('qf' 5 2.3) print(var) tup = struct.unpack('qf' var) print(tup) 

出力
b'x01x00x02x00x05x00x00x00xbdx01x00x00x00x00x00x00' (True 2 5 445) b'x05x00x00x00x00x00x00x0033x13@' (5 2.299999952316284) 

説明: この例では、まずブール (?)、short (h)、整数 (i)、long (l) をバイトにパックします。次に、struct.unpack() を使用して Python 値に変換します。 2 番目の部分では、long long 整数 (q) と浮動小数点 (f) をパックし、それらをアンパックして戻します。 float 精度により、2.3 が 2.299999952... になることに注意してください。

3. struct.calcsize(): フォーマット文字列に対応する構造体のサイズ (バイト単位) を返します。これは、圧縮されたデータを保存するために必要なスペースを判断するのに役立ちます。 構文:

struct.calcsize(fmt)

  • fmt: データ レイアウトを指定するフォーマット文字列。
Python
import struct print(struct.calcsize('?hil')) print(struct.calcsize('qf')) 

出力
16 12 

説明: 「?ヒル」 16 バイトが必要であり、 「qf」 アラインメントとプラットフォームに応じて 12 バイトが必要です。

4. struct.pack_into() と struct.unpack_from(): これらのメソッドを使用すると、指定されたオフセットから始まるバッファにデータを直接パックしたり、バッファからデータをアンパックしたりすることができます。これらは、事前に割り当てられたメモリ バッファを処理する場合、またはメモリに格納されているバイナリ データを処理する場合に特に役立ちます。

rj12 vs rj11

struct.pack_into() の構文:

struct.pack_into(fmt バッファ オフセット v1 v2 ...)

  • fmt: データ レイアウトを指定するフォーマット文字列。
  • バッファ: 書き込み可能なバッファ (例: ctypes.create_string_buffer)。
  • offset: パッキングが始まるバッファ内の開始位置。
  • v1 v2 ...: バッファにパックされる値。

struct.unpack_from() の構文:

struct.unpack_from(fmt バッファオフセット = 0)

  • FM: データレイアウトを指定するフォーマット文字列。
  • バッファ: パックされたデータを含むバッファ。
  • オフセット: 開梱を開始する開始位置 (オプション)
Python
import struct import ctypes # Allocate buffer size = struct.calcsize('hhl') buff = ctypes.create_string_buffer(size) # Pack into buffer struct.pack_into('hhl' buff 0 2 2 3) # Unpack from buffer res = struct.unpack_from('hhl' buff 0) print(res) 

出力
(2 2 3) 

説明: ここでは、ctypes を使用してバッファが作成されます。 struct.pack_into() このバッファの指定されたオフセット (この場合は 0) に値を挿入します。 struct.unpack_from() 次に、バッファからデータを読み取ります。

ぎこちないメッシュグリッド

フォーマット順序の影響

フォーマット文字の順序は、パディングと位置合わせによりパックされた出力を変更する可能性があります。これは、結果のバイト内容とサイズの両方に影響します。

Python
import struct var = struct.pack('bi' 56 0x12131415) print(var) print(struct.calcsize('bi')) var = struct.pack('ib' 0x12131415 56) print(var) print(struct.calcsize('ib')) 

出力
b'8x00x00x00x15x14x13x12' 8 b'x15x14x13x128' 5 

説明: 'bi' (バイト整数) バイトの後にパディングが含まれる場合がありますが、 'ib' (整数バイト) それは必要ありません。サイズの違い (8 対 5) は、アライメントがメモリ レイアウトにどのような影響を与えるかを示しています。

エラーの処理

struct.pack() で間違ったデータ型が使用されると、struct.error が発生します。このようなケースを安全に処理するには、try-Except を使用します。

Python
import struct try: struct.pack('h' 'invalid') # Wrong type 'invalid' is a string but 'h' expects an integer except struct.error as e: print(f'Struct Error: {e}') 

出力

Struct Error: required argument is not an integer  

説明: struct使用時のエラー処理を示します。 'h' には短い整数が必要ですが、文字列 ('invalid') が指定されたため、struct.error が発生します。 Try-Except ブロックはエラーを捕捉し、意味のあるメッセージを出力します。

参照 https://docs.python.org/2/library/struct.html