7.1. struct —バイトをパックされたバイナリデータとして解釈する—Pythonドキュメント
7.1。 構造体 —バイトをパックされたバイナリデータとして解釈します
ソースコード: :source: `Lib / struct.py`
このモジュールは、Python値とPython bytes オブジェクトとして表されるC構造体の間の変換を実行します。 これは、他のソースの中でも、ファイルまたはネットワーク接続から保存されたバイナリデータの処理に使用できます。 Format Strings を、C構造体のレイアウトとPython値への/からの意図された変換のコンパクトな説明として使用します。
ノート
デフォルトでは、特定のC構造体をパックした結果には、関連するCタイプの適切な配置を維持するためにパッドバイトが含まれます。 同様に、開梱時に位置合わせが考慮されます。 この動作は、パックされた構造体のバイトが、対応するC構造体のメモリ内のレイアウトに正確に対応するように選択されます。 プラットフォームに依存しないデータ形式を処理したり、暗黙のパッドバイトを省略したりするには、native
のサイズと配置ではなく、standard
のサイズと配置を使用します。詳細。
いくつかの struct 関数(および Struct のメソッド)は buffer 引数を取ります。 これは、 Buffer Protocol を実装し、読み取り可能または読み取り/書き込み可能なバッファーを提供するオブジェクトを指します。 その目的で使用される最も一般的なタイプは bytes と bytearray ですが、バイトの配列として表示できる他の多くのタイプは、バッファープロトコルを実装しているため、読み取り/ bytes オブジェクトから追加コピーせずに入力されます。
7.1.1。 関数と例外
このモジュールは、次の例外と機能を定義します。
- exception struct.error
- さまざまな場合に発生する例外。 引数は何が悪いのかを説明する文字列です。
- struct.pack(fmt, v1, v2, ...)
- フォーマット文字列 fmt に従ってパックされた値 v1 、 v2 、…を含むバイトオブジェクトを返します。 引数は、フォーマットに必要な値と正確に一致する必要があります。
- struct.pack_into(fmt, buffer, offset, v1, v2, ...)
- 値 v1 、 v2 、…をフォーマット文字列 fmt に従ってパックし、パックされたバイトを書き込み可能バッファ buffer に書き込みます。位置オフセット。 offset は必須の引数であることに注意してください。
- struct.unpack(fmt, buffer)
- フォーマット文字列 fmt に従って、バッファ buffer (おそらく
pack(fmt, ...)
によってパックされます)から解凍します。 結果は、アイテムが1つだけ含まれている場合でもタプルになります。 calcsize()に反映されているように、バイト単位のバッファのサイズは、フォーマットに必要なサイズと一致する必要があります。
- struct.unpack_from(fmt, buffer, offset=0)
- フォーマット文字列 fmt に従って、位置 offset から始まる buffer からアンパックします。 結果は、アイテムが1つだけ含まれている場合でもタプルになります。 offset を引いたバイト単位のバッファのサイズは、 calcsize()に反映されているように、少なくともフォーマットに必要なサイズである必要があります。
- struct.iter_unpack(fmt, buffer)
フォーマット文字列 fmt に従って、バッファ buffer から繰り返し解凍します。 この関数は、すべてのコンテンツが消費されるまで、バッファーから同じサイズのチャンクを読み取るイテレーターを返します。 calcsize()に反映されているように、バイト単位のバッファのサイズは、フォーマットに必要なサイズの倍数である必要があります。
各反復は、フォーマット文字列で指定されたタプルを生成します。
バージョン3.4の新機能。
- struct.calcsize(fmt)
- フォーマット文字列 fmt に対応する構造体のサイズ(したがって、
pack(fmt, ...)
によって生成されるbytesオブジェクトのサイズ)を返します。
7.1.2。 文字列のフォーマット
フォーマット文字列は、データをパックおよびアンパックするときに予想されるレイアウトを指定するために使用されるメカニズムです。 これらは、パック/アンパックされるデータのタイプを指定するフォーマット文字から構築されます。 さらに、バイトオーダー、サイズ、および配置を制御するための特殊文字があります。
7.1.2.1。 バイトオーダー、サイズ、および配置
デフォルトでは、C型はマシンのネイティブ形式とバイト順序で表され、必要に応じてパッドバイトをスキップすることで適切に整列されます(Cコンパイラで使用される規則に従って)。
または、次の表に従って、フォーマット文字列の最初の文字を使用して、パックされたデータのバイト順序、サイズ、および配置を示すことができます。
キャラクター | バイトオーダー | サイズ | 配置 |
---|---|---|---|
@
|
ネイティブ | ネイティブ | ネイティブ |
=
|
ネイティブ | 標準 | なし |
<
|
リトルエンディアン | 標準 | なし |
>
|
ビッグエンディアン | 標準 | なし |
!
|
ネットワーク(=ビッグエンディアン) | 標準 | なし |
最初の文字がこれらのいずれでもない場合、'@'
が想定されます。
ネイティブバイトの順序は、ホストシステムに応じて、ビッグエンディアンまたはリトルエンディアンです。 たとえば、Intel x86およびAMD64(x86-64)はリトルエンディアンです。 Motorola68000とPowerPCG5はビッグエンディアンです。 ARMおよびIntelItaniumは、切り替え可能なエンディアン(バイエンディアン)を備えています。 sys.byteorder
を使用して、システムのエンディアンを確認します。
ネイティブのサイズと配置は、Cコンパイラのsizeof
式を使用して決定されます。 これは常にネイティブバイトオーダーと組み合わされます。
標準サイズはフォーマット文字のみに依存します。 文字のフォーマットセクションの表を参照してください。
'@'
と'='
の違いに注意してください。どちらもネイティブバイトオーダーを使用しますが、後者のサイズと配置は標準化されています。
'!'
の形式は、ネットワークのバイト順序がビッグエンディアンかリトルエンディアンかを思い出せないと主張する貧しい人々が利用できます。
非ネイティブのバイト順序を示す方法はありません(バイトスワッピングを強制します)。 '<'
または'>'
の適切な選択を使用してください。
ノート:
- パディングは、連続する構造体メンバー間にのみ自動的に追加されます。 エンコードされた構造体の最初または最後にパディングは追加されません。
- 非ネイティブのサイズと配置を使用する場合、パディングは追加されません。 、 '='、および '!'を使用します。
- 構造体の終わりを特定のタイプの整列要件に整列させるには、繰り返し回数がゼロのそのタイプのコードでフォーマットを終了します。 例を参照してください。
7.1.2.2。 文字のフォーマット
フォーマット文字の意味は次のとおりです。 C値とPython値の間の変換は、それらのタイプを考えると明らかなはずです。 「標準サイズ」列は、標準サイズを使用する場合のパック値のサイズをバイト単位で示します。 つまり、フォーマット文字列が'<'
、'>'
、'!'
、または'='
のいずれかで始まる場合です。 ネイティブサイズを使用する場合、パックされた値のサイズはプラットフォームに依存します。
フォーマット | Cタイプ | Pythonタイプ | 標準サイズ | ノート |
---|---|---|---|---|
x
|
パッドバイト | 値なし | ||
c
|
char
|
長さ1のバイト | 1 | |
b
|
signed char
|
整数 | 1 | (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) |
n
|
ssize_t
|
整数 | (4) | |
N
|
size_t
|
整数 | (4) | |
e
|
(7) | 浮く | 2 | (5) |
f
|
float
|
浮く | 4 | (5) |
d
|
double
|
浮く | 8 | (5) |
s
|
char[]
|
バイト | ||
p
|
char[]
|
バイト | ||
P
|
void *
|
整数 | (6) |
バージョン3.3で変更: 'n'
および'N'
形式のサポートが追加されました。
バージョン3.6で変更: 'e'
形式のサポートが追加されました。
ノート:
'?'
変換コードは、C99で定義されている_Bool
タイプに対応しています。 このタイプが使用できない場合は、char
を使用してシミュレートされます。 標準モードでは、常に1バイトで表されます。'q'
および'Q'
変換コードは、プラットフォームCコンパイラがClong long
、またはWindowsでは__int64
をサポートしている場合にのみ、ネイティブモードで使用できます。 それらは常に標準モードで利用できます。整数変換コードのいずれかを使用して非整数をパックしようとすると、非整数に
__index__()
メソッドがある場合、そのメソッドが呼び出されて、パックする前に引数が整数に変換されます。バージョン3.2で変更:非整数に対する
__index__()
メソッドの使用は3.2の新機能です。'n'
および'N'
変換コードは、ネイティブサイズ(デフォルトとして選択されているか、'@'
バイトオーダー文字で選択されている)でのみ使用できます。 標準サイズの場合、アプリケーションに適合する他の整数形式のいずれかを使用できます。'f'
、'd'
、および'e'
変換コードの場合、パック表現はIEEE 754 binary32、binary64、またはbinary16形式('f'
、'd'
または'e'
)。'P'
形式の文字は、ネイティブのバイト順序でのみ使用できます(デフォルトとして選択されるか、'@'
バイト順序文字で選択されます)。 バイトオーダー文字'='
は、ホストシステムに基づいてリトルエンディアンまたはビッグエンディアンの順序を使用することを選択します。 構造体モジュールはこれをネイティブの順序として解釈しないため、'P'
形式は使用できません。IEEE 754バイナリ16「半精度」タイプは、 IEEE754標準の2008年リビジョンで導入されました。 符号ビット、5ビットの指数、11ビットの精度(10ビットが明示的に格納されている)を備えており、約
6.1e-05
から6.5e+04
までの数値を完全な精度で表すことができます。 このタイプは、Cコンパイラでは広くサポートされていません。通常のマシンでは、unsigned shortをストレージに使用できますが、数学演算には使用できません。 詳細については、半精度浮動小数点形式のウィキペディアのページを参照してください。
フォーマット文字の前に、整数の繰り返しカウントを付けることができます。 たとえば、フォーマット文字列'4h'
は、'hhhh'
とまったく同じ意味です。
フォーマット間の空白文字は無視されます。 ただし、カウントとその形式に空白を含めることはできません。
's'
形式の文字の場合、カウントはバイトの長さとして解釈され、他の形式の文字のように繰り返しカウントではありません。 たとえば、'10s'
は単一の10バイト文字列を意味し、'10c'
は10文字を意味します。 カウントが指定されていない場合、デフォルトで1になります。 パッキングの場合、文字列は切り捨てられるか、必要に応じてnullバイトが埋め込まれます。 解凍の場合、結果のバイトオブジェクトは常に正確に指定されたバイト数になります。 特別な場合として、'0s'
は単一の空の文字列を意味します('0c'
は0文字を意味します)。
整数形式('b'
、'B'
、'h'
、'H'
、'i'
のいずれかを使用して値x
をパックする場合]、'I'
、'l'
、'L'
、'q'
、'Q'
)、x
が有効範囲外の場合その形式の場合、 struct.error が発生します。
バージョン3.1で変更: 3.0では、一部の整数形式が範囲外の値をラップし、 struct.error ではなく DeprecationWarning を発生させました。
'p'
形式の文字は、「パスカル文字列」をエンコードします。これは、カウントで指定された固定バイト数に格納された短い可変長文字列を意味します。 保存される最初のバイトは、文字列の長さまたは255のいずれか小さい方です。 文字列のバイトが続きます。 pack()に渡される文字列が長すぎる(カウントから1を引いた長さより長い)場合、文字列の先頭のcount-1
バイトのみが格納されます。 文字列がcount-1
より短い場合は、nullバイトが埋め込まれるため、すべてのバイトが正確にカウントされます。 unpack()の場合、'p'
形式の文字はcount
バイトを消費しますが、返される文字列に255バイトを超えることはできないことに注意してください。
'?'
形式の文字の場合、戻り値は True または False のいずれかです。 パッキング時には、引数オブジェクトの真理値が使用されます。 ネイティブまたは標準のブール表現の0または1のいずれかがパックされ、ゼロ以外の値はアンパック時にTrue
になります。
7.1.2.3。 例
ノート
すべての例は、ネイティブのバイト順序、サイズ、およびビッグエンディアンマシンとのアラインメントを想定しています。
3つの整数をパック/アンパックする基本的な例:
>>> from struct import *
>>> pack('hhl', 1, 2, 3)
b'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
解凍されたフィールドには、変数に割り当てるか、結果を名前付きタプルでラップすることで名前を付けることができます。
>>> record = b'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=b'raymond ', serialnum=4658, school=264, gradelevel=8)
配置要件を満たすために必要なパディングが異なるため、フォーマット文字の順序はサイズに影響を与える可能性があります。
>>> pack('ci', b'*', 0x12131415)
b'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, b'*')
b'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5
次の形式'llh0l'
は、longが4バイト境界に整列していると仮定して、最後に2つのパッドバイトを指定します。
>>> pack('llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
これは、ネイティブのサイズと配置が有効な場合にのみ機能します。 標準のサイズと配置では、配置は強制されません。
7.1.3。 クラス
struct モジュールは、次のタイプも定義します。
- class struct.Struct(format)
フォーマット文字列 format に従ってバイナリデータを読み書きする新しいStructオブジェクトを返します。 Structオブジェクトを1回作成してそのメソッドを呼び出す方が、同じ形式で struct 関数を呼び出すよりも効率的です。これは、フォーマット文字列を1回コンパイルするだけでよいためです。
コンパイルされたStructオブジェクトは、次のメソッドと属性をサポートします。
- pack_into(buffer, offset, v1, v2, ...)
コンパイルされた形式を使用して、 pack_into()関数と同じです。
- unpack_from(buffer, offset=0)
コンパイルされた形式を使用して、 unpack_from()関数と同じです。 バイト単位のバッファのサイズからオフセットを引いたものは、少なくともサイズである必要があります。
- iter_unpack(buffer)
コンパイルされた形式を使用して、 iter_unpack()関数と同じです。 バイト単位のバッファのサイズは、 size の倍数である必要があります。
バージョン3.4の新機能。
- format
このStructオブジェクトの作成に使用されるフォーマット文字列。