struct
--- バイト列をパックされたバイナリデータとして解釈する¶
ソースコード: Lib/struct.py
This module converts between Python values and C structs represented
as Python bytes
objects. Compact format strings
describe the intended conversions to/from Python values.
The module's functions and objects can be used for two largely
distinct applications, data exchange with external sources (files or
network connections), or data transfer between the Python application
and the C layer.
注釈
When no prefix character is given, native mode is the default. It packs or unpacks data based on the platform and compiler on which the Python interpreter was built. The result of packing a given C struct includes pad bytes which maintain proper alignment for the C types involved; similarly, alignment is taken into account when unpacking. In contrast, when communicating data between external sources, the programmer is responsible for defining byte ordering and padding between elements. See バイトオーダ、サイズ、アラインメント for details.
いくつかの struct
の関数 (および Struct
のメソッド) は buffer 引数を取ります。 これは バッファプロトコル (buffer Protocol) を実装していて読み取り可能または読み書き可能なバッファを提供するオブジェクトのことです。この目的のために使われる最も一般的な型は bytes
と bytearray
ですが、バイトの配列とみなすことができるような他の多くの型がバッファプロトコルを実装しています。そのため、それらは bytes
オブジェクトから追加のコピーなしで読み出しや書き込みができます。
関数と例外¶
このモジュールは以下の例外と関数を定義しています:
- exception struct.error¶
様々な状況で送出される例外です。引数は何が問題なのかを記述する文字列です。
- struct.pack(format, v1, v2, ...)¶
フォーマット文字列 format に従い値 v1, v2, ... をパックして、バイト列オブジェクトを返します。引数は指定したフォーマットが要求する型と正確に一致していなければなりません。
- struct.pack_into(format, buffer, offset, v1, v2, ...)¶
フォーマット文字列 format に従い値 v1, v2, ... をパックしてバイト列にし、書き込み可能な buffer のオフセット offset 位置より書き込みます。オフセットは省略出来ません。
- struct.unpack(format, buffer)¶
(
pack(format, ...)
でパックされたであろう) バッファ buffer を、書式文字列 format に従ってアンパックします。 値が一つしかない場合を含め、結果はタプルで返されます。 バッファのバイトサイズは、calcsize()
の返り値である書式文字列が要求するサイズと一致しなければなりません。
- struct.unpack_from(format, /, buffer, offset=0)¶
バッファ buffer を、 offset の位置から書式文字列 format に従ってアンパックします。 値が一つしかない場合を含め、結果はタプルで返されます。 offset を始点とするバッファのバイトサイズは、少なくとも
calcsize()
の返り値である書式文字列が要求するサイズでなければなりません。
- struct.iter_unpack(format, buffer)¶
バッファ buffer を、書式文字列 format に従ってイテレータ形式でアンパックします。 この関数が返すイテレータは、すべての内容を読み終わるまでバッファから一定の大きさのチャンクを読み取ります。 バッファのバイトサイズは、
calcsize()
の返り値である書式文字列が要求するサイズの倍数でなければなりません。イテレーション毎に書式文字列で指定されたタプルを yield します。
Added in version 3.4.
- struct.calcsize(format)¶
書式文字列 format に従って、構造体 (それと
pack(format, ...)
によって作成されるバイト列オブジェクト) のサイズを返します。
書式文字列¶
Format strings describe the data layout when packing and unpacking data. They are built up from format characters, which specify the type of data being packed/unpacked. In addition, special characters control the byte order, size and alignment. Each format string consists of an optional prefix character which describes the overall properties of the data and one or more format characters which describe the actual data values and padding.
バイトオーダ、サイズ、アラインメント¶
By default, C types are represented in the machine's native format and byte order, and properly aligned by skipping pad bytes if necessary (according to the rules used by the C compiler). This behavior is chosen so that the bytes of a packed struct correspond exactly to the memory layout of the corresponding C struct. Whether to use native byte ordering and padding or standard formats depends on the application.
これに代わって、フォーマット文字列の最初の文字を使って、バイトオーダやサイズ、アラインメントを指定することができます。指定できる文字を以下のテーブルに示します:
文字 |
バイトオーダ |
サイズ |
アラインメント |
---|---|---|---|
|
native |
native |
native |
|
native |
standard |
none |
|
リトルエンディアン |
standard |
none |
|
ビッグエンディアン |
standard |
none |
|
ネットワーク (= ビッグエンディアン) |
standard |
none |
フォーマット文字列の最初の文字が上のいずれかでない場合、'@'
であるとみなされます。
注釈
The number 1023 (0x3ff
in hexadecimal) has the following byte representations:
03 ff
in big-endian (>
)ff 03
in little-endian (<
)
Python の例:
>>> import struct
>>> struct.pack('>h', 1023)
b'\x03\xff'
>>> struct.pack('<h', 1023)
b'\xff\x03'
ネイティブのバイトオーダはビッグエンディアンかリトルエンディアンで、ホストシステムに依存します。例えば、Intel x86、AMD64 (x86-64) および Apple M1 はリトルエンディアンです。IBM z および多くの古いアーキテクチャはビッグエンディアンです。使っているシステムでのエンディアンは sys.byteorder
を使って調べて下さい。
ネイティブのサイズおよびアラインメントは C コンパイラの sizeof
式で決定されます。ネイティブのサイズおよびアラインメントはネイティブのバイトオーダと同時に使われます。
標準のサイズはフォーマット文字だけで決まります。 書式指定文字 の表を参照して下さい。
'@'
と '='
の違いに注意してください: 両方ともネイティブのバイトオーダですが、後者のバイトサイズとアラインメントは標準のものに合わせてあります。
The form '!'
represents the network byte order which is always big-endian
as defined in IETF RFC 1700.
バイトオーダに関して、「(強制的にバイトスワップを行う)ネイティブの逆」を指定する方法はありません。'<'
または '>'
のうちふさわしい方を選んでください。
注釈:
パディングは構造体のメンバの並びの中にだけ自動で追加されます。最初や最後にパディングが追加されることはありません。
ネイティブでないサイズおよびアラインメントが使われる場合にはパディングは行われません (たとえば '<', '>', '=', '!' を使った場合です)。
特定の型によるアラインメント要求に従うように構造体の末端をそろえるには、繰り返し回数をゼロにした特定の型でフォーマットを終端します。 使用例 を参照して下さい。
書式指定文字¶
フォーマット文字 (format character) は以下の意味を持っています; C と Python の間の変換では、値は正確に以下に指定された型でなくてはなりません: 「標準のサイズ」列は standard サイズ使用時にパックされた値が何バイトかを示します。つまり、フォーマット文字列が '<'
, '>'
, '!'
, '='
のいずれかで始まっている場合のものです。native サイズ使用時にはパックされた値の大きさはプラットフォーム依存です。
フォーマット |
C の型 |
Python の型 |
標準のサイズ |
注釈 |
---|---|---|---|---|
|
パディングバイト |
値なし |
(7) |
|
|
char |
長さ 1 のバイト列 |
1 |
|
|
signed char |
整数 |
1 |
(1), (2) |
|
unsigned char |
整数 |
1 |
(2) |
|
_Bool |
真偽値型(bool) |
1 |
(1) |
|
short |
整数 |
2 |
(2) |
|
unsigned short |
整数 |
2 |
(2) |
|
int |
整数 |
4 |
(2) |
|
unsigned int |
整数 |
4 |
(2) |
|
long |
整数 |
4 |
(2) |
|
unsigned long |
整数 |
4 |
(2) |
|
long long |
整数 |
8 |
(2) |
|
unsigned long long |
整数 |
8 |
(2) |
|
|
整数 |
(3) |
|
|
|
整数 |
(3) |
|
|
(6) |
浮動小数点数 |
2 |
(4) |
|
float |
浮動小数点数 |
4 |
(4) |
|
double |
浮動小数点数 |
8 |
(4) |
|
char[] |
bytes |
(9) |
|
|
char[] |
bytes |
(8) |
|
|
void* |
整数 |
(5) |
バージョン 3.3 で変更: 'n'
および 'N'
フォーマットのサポートが追加されました。
バージョン 3.6 で変更: 'e'
フォーマットのサポートが追加されました。
注釈:
The
'?'
conversion code corresponds to the _Bool type defined by C standards since C99. In standard mode, it is represented by one byte.When attempting to pack a non-integer using any of the integer conversion codes, if the non-integer has a
__index__()
method then that method is called to convert the argument to an integer before packing.バージョン 3.2 で変更: Added use of the
__index__()
method for non-integers.'n'
および'N'
変換コードは (デフォルトもしくはバイトオーダ文字'@'
付きで選択される) native サイズ使用時のみ利用できます。standard サイズ使用時には、自身のアプリケーションに適する他の整数フォーマットを使うことができます。'f'
、'd'
および'e'
変換コードについて、パックされた表現は IEEE 754 binary32 ('f'
の場合) 、 binary64 ('d'
の場合) 、またはbinary16('e'
の場合) フォーマットが、プラットフォームにおける浮動小数点数のフォーマットに関係なく使われます。'P'
フォーマット文字はネイティブバイトオーダでのみ利用可能です (デフォルトのネットワークバイトオーダに設定するか、'@'
バイトオーダ指定文字を指定しなければなりません)。'='
を指定した場合、ホスト計算機のバイトオーダに基づいてリトルエンディアンとビッグエンディアンのどちらを使うかを決めます。struct モジュールはこの設定をネイティブのオーダ設定として解釈しないので、'P'
を使うことはできません。IEEE 754 の binary16 "半精度" 型は、 IEEE 754 standard の2008 年の改訂で導入されました。 半精度型は、符号 bit 、5 bit の指数部、 11 bit の精度 (明示的には 10 bit が保存される) を持ち、おおよそ
6.1e-05
から6.5e+04
までの数を完全な精度で表現できます。 この型は C コンパイラでは広くはサポートされていません: たいていのマシンでは、保存するのに unsigned short が使えますが、数学の演算には使えません。 詳しいことは Wikipedia の half-precision floating-point format のページを参照してください。When packing,
'x'
inserts one NUL byte.フォーマット文字
'p'
は "Pascal 文字列 (pascal string)" をコードします。Pascal 文字列は count で与えられる 固定長のバイト列 に収められた短い可変長の文字列です。このデータの先頭の 1 バイトには文字列の長さか255 のうち、小さい方の数が収められます。その後に文字列のバイトデータが続きます。pack()
に渡された Pascal 文字列の長さが長すぎた (count-1 よりも長い) 場合、先頭のcount-1
バイトが書き込まれます。文字列がcount-1
よりも短い場合、指定した count バイトに達するまでの残りの部分はヌルで埋められます。unpack()
では、フォーマット文字'p'
は指定されたcount
バイトだけデータを読み込みますが、返される文字列は決して 255 文字を超えることはないので注意してください。For the
's'
format character, the count is interpreted as the length of the bytes, not a repeat count like for the other format characters; for example,'10s'
means a single 10-byte string mapping to or from a single Python byte string, while'10c'
means 10 separate one byte character elements (e.g.,cccccccccc
) mapping to or from ten different Python byte objects. (See 使用例 for a concrete demonstration of the difference.) If a count is not given, it defaults to 1. For packing, the string is truncated or padded with null bytes as appropriate to make it fit. For unpacking, the resulting bytes object always has exactly the specified number of bytes. As a special case,'0s'
means a single, empty string (while'0c'
means 0 characters).
フォーマット文字の前に整数をつけ、繰り返し回数 (count) を指定することができます。例えば、フォーマット文字列 '4h'
は 'hhhh'
と全く同じ意味です。
フォーマット文字間の空白文字は無視されます; count とフォーマット文字の間にはスペースを入れてはいけません。
整数フォーマット ('b'
, 'B'
, 'h'
, 'H'
, 'i'
, 'I'
, 'l'
, 'L'
, 'q'
, 'Q'
) のいずれかを使って値 x
をパックするとき x
がフォーマットの適切な値の範囲に無い場合、 struct.error
が送出されます。
バージョン 3.1 で変更: 以前は、いくつかの整数フォーマットが適切な範囲にない値を覆い隠して、 struct.error
の代わりに DeprecationWarning
を送出していました。
'?'
フォーマット文字では、返り値は True
または False
です。パックするときには、引数オブジェクトの論理値としての値が使われます。 0 または 1 のネイティブや標準の真偽値表現でパックされ、アンパックされるときはゼロでない値は True
になります。
使用例¶
注釈
Native byte order examples (designated by the '@'
format prefix or
lack of any prefix character) may not match what the reader's
machine produces as
that depends on the platform and compiler.
Pack and unpack integers of three different sizes, using big endian ordering:
>>> from struct import *
>>> pack(">bhl", 1, 2, 3)
b'\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('>bhl', b'\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('>bhl')
7
Attempt to pack an integer which is too large for the defined field:
>>> pack(">h", 99999)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: 'h' format requires -32768 <= number <= 32767
Demonstrate the difference between 's'
and 'c'
format
characters:
>>> pack("@ccc", b'1', b'2', b'3')
b'123'
>>> pack("@3s", b'123')
b'123'
アンパックした結果のフィールドは、変数に割り当てるか named tuple でラップすることによって名前を付けることができます:
>>> 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)
The ordering of format characters may have an impact on size in native
mode since padding is implicit. In standard mode, the user is
responsible for inserting any desired padding.
Note in
the first pack
call below that three NUL bytes were added after the
packed '#'
to align the following integer on a four-byte boundary.
In this example, the output was produced on a little endian machine:
>>> pack('@ci', b'#', 0x12131415)
b'#\x00\x00\x00\x15\x14\x13\x12'
>>> pack('@ic', 0x12131415, b'#')
b'\x15\x14\x13\x12#'
>>> calcsize('@ci')
8
>>> calcsize('@ic')
5
The following format 'llh0l'
results in two pad bytes being added
at the end, assuming the platform's longs are aligned on 4-byte boundaries:
>>> pack('@llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
Applications¶
Two main applications for the struct
module exist, data
interchange between Python and C code within an application or another
application compiled using the same compiler (native formats), and
data interchange between applications using agreed upon data layout
(standard formats). Generally speaking, the format strings
constructed for these two domains are distinct.
Native Formats¶
When constructing format strings which mimic native layouts, the
compiler and machine architecture determine byte ordering and padding.
In such cases, the @
format character should be used to specify
native byte ordering and data sizes. Internal pad bytes are normally inserted
automatically. It is possible that a zero-repeat format code will be
needed at the end of a format string to round up to the correct
byte boundary for proper alignment of consecutive chunks of data.
Consider these two simple examples (on a 64-bit, little-endian machine):
>>> calcsize('@lhl')
24
>>> calcsize('@llh')
18
Data is not padded to an 8-byte boundary at the end of the second format string without the use of extra padding. A zero-repeat format code solves that problem:
>>> calcsize('@llh0l')
24
The 'x'
format code can be used to specify the repeat, but for
native formats it is better to use a zero-repeat format like '0l'
.
By default, native byte ordering and alignment is used, but it is
better to be explicit and use the '@'
prefix character.
Standard Formats¶
When exchanging data beyond your process such as networking or storage,
be precise. Specify the exact byte order, size, and alignment. Do
not assume they match the native order of a particular machine.
For example, network byte order is big-endian, while many popular CPUs
are little-endian. By defining this explicitly, the user need not
care about the specifics of the platform their code is running on.
The first character should typically be <
or >
(or !
). Padding is the responsibility of the programmer. The
zero-repeat format character won't work. Instead, the user must
explicitly add 'x'
pad bytes where needed. Revisiting the
examples from the previous section, we have:
>>> calcsize('<qh6xq')
24
>>> pack('<qh6xq', 1, 2, 3) == pack('@lhl', 1, 2, 3)
True
>>> calcsize('@llh')
18
>>> pack('@llh', 1, 2, 3) == pack('<qqh', 1, 2, 3)
True
>>> calcsize('<qqh6x')
24
>>> calcsize('@llh0l')
24
>>> pack('@llh0l', 1, 2, 3) == pack('<qqh6x', 1, 2, 3)
True
The above results (executed on a 64-bit machine) aren't guaranteed to match when executed on different machines. For example, the examples below were executed on a 32-bit machine:
>>> calcsize('<qqh6x')
24
>>> calcsize('@llh0l')
12
>>> pack('@llh0l', 1, 2, 3) == pack('<qqh6x', 1, 2, 3)
False
クラス¶
struct
モジュールは次の型を定義します:
- class struct.Struct(format)¶
フォーマット文字列 format に従ってバイナリデータを読み書きする、新しい Struct オブジェクトを返します。
Struct
オブジェクトを一度作ってからそのメソッドを呼び出すと、フォーマット文字列のコンパイルが一度だけになるので、モジュールレベルの関数を同じフォーマットで呼び出すよりも効率的です。注釈
The compiled versions of the most recent format strings passed to the module-level functions are cached, so programs that use only a few format strings needn't worry about reusing a single
Struct
instance.コンパイルされた Struct オブジェクトは以下のメソッドと属性をサポートします:
- pack_into(buffer, offset, v1, v2, ...)¶
pack_into()
関数と同じ、コンパイルされたフォーマットを利用するメソッドです。
- unpack_from(buffer, offset=0)¶
unpack_from()
関数と同じ、コンパイルされたフォーマットを利用するメソッドです。 (offset を始点とする buffer のバイト数は少なくともsize
以上でなければなりません)。
- iter_unpack(buffer)¶
iter_unpack()
関数と同じ、コンパイルされたフォーマットを利用するメソッドです。 (buffer のバイト数はsize
の倍数でなければなりません)。Added in version 3.4.
- format¶
この Struct オブジェクトを作成する時に利用されたフォーマット文字列です。
バージョン 3.13 で変更: The repr() of structs has changed. It is now:
>>> Struct('i') Struct('i')