7.3. struct —文字列をパックされたバイナリデータとして解釈する—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/2.7/library/struct
移動先:案内検索

7.3。 構造体 —文字列をパックされたバイナリデータとして解釈します

このモジュールは、Python値とPython文字列として表されるC構造体の間の変換を実行します。 これは、他のソースの中でも、ファイルまたはネットワーク接続から保存されたバイナリデータの処理に使用できます。 Format Strings を、C構造体のレイアウトとPython値への/からの意図された変換のコンパクトな説明として使用します。

ノート

デフォルトでは、特定のC構造体をパックした結果には、関連するCタイプの適切な配置を維持するためにパッドバイトが含まれます。 同様に、開梱時に位置合わせが考慮されます。 この動作は、パックされた構造体のバイトが、対応するC構造体のメモリ内のレイアウトに正確に対応するように選択されます。 プラットフォームに依存しないデータ形式を処理したり、暗黙のパッドバイトを省略したりするには、nativeのサイズと配置ではなく、standardのサイズと配置を使用します。詳細。


7.3.1。 関数と例外

このモジュールは、次の例外と機能を定義します。

exception struct.error
さまざまな場合に発生する例外。 引数は何が悪いのかを説明する文字列です。
struct.pack(fmt, v1, v2, ...)
指定された形式に従ってパックされた値v1, v2, ...を含む文字列を返します。 引数は、フォーマットに必要な値と正確に一致する必要があります。
struct.pack_into(fmt, buffer, offset, v1, v2, ...)

指定された形式に従って値v1, v2, ...をパックし、パックされたバイトを offset から始まる書き込み可能なバッファに書き込みます。 オフセットは必須の引数であることに注意してください。

バージョン2.5の新機能。

struct.unpack(fmt, string)
指定された形式に従って文字列を解凍します(おそらくpack(fmt, ...)によってパックされます)。 結果は、アイテムが1つだけ含まれている場合でもタプルになります。 文字列には、フォーマットに必要なデータ量が正確に含まれている必要があります(len(string)calcsize(fmt)と等しくなければなりません)。
struct.unpack_from(fmt, buffer[, offset=0])

指定された形式に従ってバッファを解凍します。 結果は、アイテムが1つだけ含まれている場合でもタプルになります。 バッファには、少なくともフォーマットに必要な量のデータが含まれている必要があります(len(buffer[offset:])は少なくともcalcsize(fmt)である必要があります)。

バージョン2.5の新機能。

struct.calcsize(fmt)
指定された形式に対応する構造体のサイズ(したがって文字列のサイズ)を返します。


7.3.2。 文字列のフォーマット

フォーマット文字列は、データをパックおよびアンパックするときに予想されるレイアウトを指定するために使用されるメカニズムです。 これらは、パック/アンパックされるデータのタイプを指定するフォーマット文字から構築されます。 さらに、バイトオーダー、サイズ、および配置を制御するための特殊文字があります。

7.3.2.1。 バイトオーダー、サイズ、および配置

デフォルトでは、C型はマシンのネイティブ形式とバイト順序で表され、必要に応じてパッドバイトをスキップすることで適切に整列されます(Cコンパイラで使用される規則に従って)。

または、次の表に従って、フォーマット文字列の最初の文字を使用して、パックされたデータのバイト順序、サイズ、および配置を示すことができます。

キャラクター バイトオーダー サイズ 配置
@ ネイティブ ネイティブ ネイティブ
= ネイティブ 標準 なし
< リトルエンディアン 標準 なし
> ビッグエンディアン 標準 なし
! ネットワーク(=ビッグエンディアン) 標準 なし

最初の文字がこれらのいずれでもない場合、'@'が想定されます。

ネイティブバイトの順序は、ホストシステムに応じて、ビッグエンディアンまたはリトルエンディアンです。 たとえば、Intel x86およびAMD64(x86-64)はリトルエンディアンです。 Motorola68000とPowerPCG5はビッグエンディアンです。 ARMおよびIntelItaniumは、切り替え可能なエンディアン(バイエンディアン)を備えています。 sys.byteorderを使用して、システムのエンディアンを確認します。

ネイティブのサイズと配置は、Cコンパイラのsizeof式を使用して決定されます。 これは常にネイティブバイトオーダーと組み合わされます。

標準サイズはフォーマット文字のみに依存します。 文字のフォーマットセクションの表を参照してください。

'@''='の違いに注意してください。どちらもネイティブバイトオーダーを使用しますが、後者のサイズと配置は標準化されています。

'!'の形式は、ネットワークのバイト順序がビッグエンディアンかリトルエンディアンかを思い出せないと主張する貧しい人々が利用できます。

非ネイティブのバイト順序を示す方法はありません(バイトスワッピングを強制します)。 '<'または'>'の適切な選択を使用してください。

ノート:

  1. パディングは、連続する構造体メンバー間にのみ自動的に追加されます。 エンコードされた構造体の最初または最後にパディングは追加されません。
  2. 非ネイティブのサイズと配置を使用する場合、パディングは追加されません。 、 '='、および '!'を使用します。
  3. 構造体の終わりを特定のタイプの整列要件に整列させるには、繰り返し回数がゼロのそのタイプのコードでフォーマットを終了します。 を参照してください。


7.3.2.2。 文字のフォーマット

フォーマット文字の意味は次のとおりです。 C値とPython値の間の変換は、それらのタイプを考えると明らかなはずです。 「標準サイズ」列は、標準サイズを使用する場合のパック値のサイズをバイト単位で示します。 つまり、フォーマット文字列が'<''>''!'、または'='のいずれかで始まる場合です。 ネイティブサイズを使用する場合、パックされた値のサイズはプラットフォームに依存します。

フォーマット Cタイプ Pythonタイプ 標準サイズ ノート
x パッドバイト 値なし
c char 長さ1の文字列 1
b signed char 整数 1 (3)
B unsigned char 整数 1 (3)
? _Bool ブール 1 (1)
h short 整数 2 (3)
H unsigned short 整数 2 (3)
i int 整数 4 (3)
I unsigned int 整数 4 (3)
l long 整数 4 (3)
L unsigned long 整数 4 (3)
q long long 整数 8 (2), (3)
Q unsigned long long 整数 8 (2), (3)
f float 浮く 4 (4)
d double 浮く 8 (4)
s char[] ストリング
p char[] ストリング
P void * 整数 (5), (3)

ノート:

  1. '?'変換コードは、C99で定義されている_Boolタイプに対応しています。 このタイプが使用できない場合は、charを使用してシミュレートされます。 標準モードでは、常に1バイトで表されます。

    バージョン2.6の新機能。

  2. 'q'および'Q'変換コードは、プラットフォームCコンパイラがC long long、またはWindowsでは__int64をサポートしている場合にのみ、ネイティブモードで使用できます。 それらは常に標準モードで利用できます。

    バージョン2.2の新機能。

  3. 整数変換コードのいずれかを使用して非整数をパックしようとすると、非整数に__index__()メソッドがある場合、そのメソッドが呼び出されて、パックする前に引数が整数に変換されます。 __index__()メソッドが存在しない場合、または__index__()を呼び出すとTypeErrorが発生する場合、__int__()メソッドが試行されます。 ただし、__int__()の使用は非推奨であり、DeprecationWarningが発生します。

    バージョン2.7で変更:非整数に対する__index__()メソッドの使用は2.7の新機能です。

    バージョン2.7での変更:バージョン2.7より前では、すべての整数変換コードが__int__()メソッドを使用して変換するわけではなく、DeprecationWarningはfloat引数に対してのみ発生していました。

  4. 'f'および'd'変換コードの場合、パックされた表現は、IEEE 754 binary32('f'の場合)またはbinary64('d'の場合)形式を使用します。プラットフォームで使用される浮動小数点形式。

  5. 'P'形式の文字は、ネイティブのバイト順序でのみ使用できます(デフォルトとして選択されるか、'@'バイト順序文字で選択されます)。 バイトオーダー文字'='は、ホストシステムに基づいてリトルエンディアンまたはビッグエンディアンの順序を使用することを選択します。 構造体モジュールはこれをネイティブの順序として解釈しないため、'P'形式は使用できません。

フォーマット文字の前に、整数の繰り返しカウントを付けることができます。 たとえば、フォーマット文字列'4h'は、'hhhh'とまったく同じ意味です。

フォーマット間の空白文字は無視されます。 ただし、カウントとその形式に空白を含めることはできません。

's'形式の文字の場合、カウントは文字列のサイズとして解釈され、他の形式の文字のように繰り返しカウントではありません。 たとえば、'10s'は単一の10バイト文字列を意味し、'10c'は10文字を意味します。 カウントが指定されていない場合、デフォルトで1になります。 パッキングの場合、文字列は切り捨てられるか、必要に応じてnullバイトが埋め込まれます。 解凍の場合、結果の文字列は常に正確に指定されたバイト数になります。 特別な場合として、'0s'は単一の空の文字列を意味します('0c'は0文字を意味します)。

'p'形式の文字は、「パスカル文字列」をエンコードします。これは、カウントで指定された固定バイト数に格納された短い可変長文字列を意味します。 保存される最初のバイトは、文字列の長さまたは255のいずれか小さい方です。 文字列のバイトが続きます。 pack()に渡される文字列が長すぎる(カウントから1を引いた長さより長い)場合、文字列の先頭のcount-1バイトのみが格納されます。 文字列がcount-1より短い場合は、nullバイトが埋め込まれるため、すべてのバイトが正確にカウントされます。 unpack()の場合、'p'形式の文字はカウントバイトを消費しますが、返される文字列に255文字を超えることはできないことに注意してください。

'P'形式の文字の場合、戻り値は、整数型にキャストされたときにポインターを保持するために必要なサイズに応じて、Python整数または長整数です。 NULL ポインターは、常にPython整数0として返されます。 ポインタサイズの値をパックする場合、Python整数または長整数オブジェクトを使用できます。 たとえば、AlphaおよびMercedプロセッサは64ビットのポインタ値を使用します。つまり、Pythonの長整数がポインタを保持するために使用されます。 他のプラットフォームは32ビットポインターを使用し、Python整数を使用します。

'?'形式の文字の場合、戻り値は True または False のいずれかです。 パッキング時には、引数オブジェクトの真理値が使用されます。 ネイティブまたは標準のブール表現の0または1のいずれかがパックされ、ゼロ以外の値はアンパック時にTrueになります。


7.3.2.3。 例

ノート

すべての例は、ネイティブのバイト順序、サイズ、およびビッグエンディアンマシンとのアラインメントを想定しています。


3つの整数をパック/アンパックする基本的な例:

>>> from struct import *
>>> pack('hhl', 1, 2, 3)
'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', '\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8

解凍されたフィールドには、変数に割り当てるか、結果を名前付きタプルでラップすることで名前を付けることができます。

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

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name='raymond   ', serialnum=4658, school=264, gradelevel=8)

配置要件を満たすために必要なパディングが異なるため、フォーマット文字の順序はサイズに影響を与える可能性があります。

>>> pack('ci', '*', 0x12131415)
'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, '*')
'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5

次の形式'llh0l'は、longが4バイト境界に整列していると仮定して、最後に2つのパッドバイトを指定します。

>>> pack('llh0l', 1, 2, 3)
'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'

これは、ネイティブのサイズと配置が有効な場合にのみ機能します。 標準のサイズと配置では、配置は強制されません。

も参照してください

モジュールアレイ
同種データのパックされたバイナリストレージ。
モジュール xdrlib
XDRデータのパックとアンパック。


7.3.3。 クラス

struct モジュールは、次のタイプも定義します。

class struct.Struct(format)

フォーマット文字列 format に従ってバイナリデータを読み書きする新しいStructオブジェクトを返します。 Structオブジェクトを1回作成してそのメソッドを呼び出す方が、 struct 関数を同じ形式で呼び出すよりも効率的です。これは、フォーマット文字列を1回コンパイルするだけでよいためです。

バージョン2.5の新機能。

コンパイルされたStructオブジェクトは、次のメソッドと属性をサポートします。

pack(v1, v2, ...)

コンパイルされた形式を使用して、 pack()関数と同じです。 (len(result)self.sizeと等しくなります。)

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

コンパイルされた形式を使用して、 pack_into()関数と同じです。

unpack(string)

コンパイルされた形式を使用して、 unpack()関数と同じです。 (len(string)self.sizeと等しくなければなりません)。

unpack_from(buffer, offset=0)

コンパイルされた形式を使用して、 unpack_from()関数と同じです。 (len(buffer[offset:])は少なくともself.sizeである必要があります)。

format

このStructオブジェクトの作成に使用されるフォーマット文字列。

size

format に対応する構造体(したがって文字列)の計算されたサイズ。