# 7.3. `struct` — Interpret strings as packed binary data

This module performs conversions between Python values and C structs represented as Python strings. This can be used in handling binary data stored in files or from network connections, among other sources. It uses 格式字符串 as compact descriptions of the layout of the C structs and the intended conversion to/from Python values.

注解

默认情况下，打包给定 C 结构的结果会包含填充字节以使得所涉及的 C 类型保持正确的对齐；类似地，对齐在解包时也会被纳入考虑。 选择此种行为的目的是使得被打包结构的字节能与相应 C 结构在内存中的布局完全一致。 要处理平台独立的数据格式或省略隐式的填充字节，请使用 `standard` 大小和对齐而不是 `native` 大小和对齐：详情参见 字节顺序，大小和对齐方式。

## 7.3.1. 函数和异常

此模块定义了下列异常和函数：

exception `struct.``error`

  会在多种场合下被引发的异常；其参数为一个描述错误信息的字符串。

`struct.``pack`(fmt, v1, v2, ...)

  Return a string containing the values `v1, v2, ...` packed according to the given format. The arguments must match the values required by the format exactly.

`struct.``pack_into`(fmt, buffer, offset, v1, v2, ...)

  Pack the values `v1, v2, ...` according to the given format, write the packed bytes into the writable buffer starting at offset. Note that the offset is a required argument.

  2.5 新版功能.

`struct.``unpack`(fmt, string)

  Unpack the string (presumably packed by `pack(fmt, ...)`) according to the given format. The result is a tuple even if it contains exactly one item. The string must contain exactly the amount of data required by the format (`len(string)` must equal `calcsize(fmt)`).

`struct.``unpack_from`(fmt, buffer[, offset=0])

  Unpack the buffer according to the given format. The result is a tuple even if it contains exactly one item. The buffer must contain at least the amount of data required by the format (`len(buffer[offset:])` must be at least `calcsize(fmt)`).

  2.5 新版功能.

`struct.``calcsize`(fmt)

  Return the size of the struct (and hence of the string) corresponding to the given format.

## 7.3.2. 格式字符串

格式字符串是用来在打包和解包数据时指定预期布局的机制。 它们使用指定被打包/解包数据类型的 格式字符 进行构建。 此外，还有一些特殊字符用来控制 字节顺序，大小和对齐方式。

### 7.3.2.1. 字节顺序，大小和对齐方式

默认情况下，C类型以机器的本机格式和字节顺序表示，并在必要时通过跳过填充字节进行正确对齐（根据C编译器使用的规则）。

或者，根据下表，格式字符串的第一个字符可用于指示打包数据的字节顺序，大小和对齐方式：

字符 | 字节顺序 | 大小 | 对齐方式
--- | --- | --- | ---
`@` | 按原字节 | 按原字节 | 按原字节
`=` | 按原字节 | 标准 | 无
`<` | 小端 | 标准 | 无
`>` | 大端 | 标准 | 无
`!` | 网络（=大端） | 标准 | 无

如果第一个字符不是其中之一，则假定为 `'@'` 。

本机字节顺序可能为大端或是小端，取决于主机系统的不同。 例如， Intel x86 和 AMD64 (x86-64) 是小端的；Motorola 68000 和 PowerPC G5 是大端的；ARM 和 Intel Itanium 具有可切换的字节顺序（双端）。 请使用 `sys.byteorder` 来检查你的系统字节顺序。

本机大小和对齐方式是使用 C 编译器的 `sizeof` 表达式来确定的。 这总是会与本机字节顺序相绑定。

标准大小仅取决于格式字符；请参阅 格式字符 部分中的表格。

请注意 `'@'` 和 `'='` 之间的区别：两个都使用本机字节顺序，但后者的大小和对齐方式是标准化的。

格式 `'!'` 适合给那些宣称他们记不得网络字节顺序是大端还是小端的可怜人使用。

没有什么方式能指定非本机字节顺序（强制字节对调）；请正确选择使用 `'<'` 或 `'>'`。

注释:

1. 填充只会在连续结构成员之间自动添加。 填充不会添加到已编码结构的开头和末尾。

2. 当使用非本机大小和对齐方式即 ‘<’, ‘>’, ‘=’, and ‘!’ 时不会添加任何填充。

3. 要将结构的末尾对齐到符合特定类型的对齐要求，请以该类型代码加重复计数的零作为格式结束。 参见 例子。

### 7.3.2.2. 格式字符

格式字符具有以下含义；C 和 Python 值之间的按其指定类型的转换应当是相当明显的。 ‘标准大小’列是指当使用标准大小时以字节表示的已打包值大小；也就是当格式字符串以 `'<'`, `'>'`, `'!'` 或 `'='` 之一开头的情况。 当使用本机大小时，已打包值的大小取决于具体的平台。

格式 | C 类型 | Python 类型 | 标准大小 | 注释
--- | --- | --- | --- | ---
`x` | 填充字节 | 无 |  |
`c` | `char` | string of length 1 | 1 |
`b` | `signed char` | 整数 | 1 | (3)
`B` | `unsigned char` | 整数 | 1 | (3)
`?` | `_Bool` | 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[]` | string |  |
`p` | `char[]` | string |  |
`P` | `void *` | 整数 |  | (5), (3)

注释:

1. `'?'` 转换码对应于 C99 定义的 `_Bool` 类型。 如果此类型不可用，则使用 `char` 来模拟。 在标准模式下，它总是以一个字节表示。

   2.6 新版功能.

2. The `'q'` and `'Q'` conversion codes are available in native mode only if the platform C compiler supports C `long long`, or, on Windows, `__int64`. They are always available in standard modes.

   2.2 新版功能.

3. 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. If no `__index__()` method exists, or the call to `__index__()` raises `TypeError`, then the `__int__()` method is tried. However, the use of `__int__()` is deprecated, and will raise `DeprecationWarning`.

   在 2.7 版更改: Use of the `__index__()` method for non-integers is new in 2.7.

   在 2.7 版更改: Prior to version 2.7, not all integer conversion codes would use the `__int__()` method to convert, and `DeprecationWarning` was raised only for float arguments.

4. For the `'f'` and `'d'` conversion codes, the packed representation uses the IEEE 754 binary32 (for `'f'`) or binary64 (for `'d'`) format, regardless of the floating-point format used by the platform.

5. `'P'` 格式字符仅对本机字节顺序可用（选择为默认或使用 `'@'` 字节顺序字符）。 字节顺序字符 `'='` 选择使用基于主机系统的小端或大端排序。 struct 模块不会将其解读为本机排序，因此 `'P'` 格式将不可用。

格式字符之前可以带有整数重复计数。 例如，格式字符串 `'4h'` 的含义与 `'hhhh'` 完全相同。

格式之间的空白字符会被忽略；但是计数及其格式字符中不可有空白字符。

For the `'s'` format character, the count is interpreted as the size of the string, not a repeat count like for the other format characters; for example, `'10s'` means a single 10-byte string, while `'10c'` means 10 characters. 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 string always has exactly the specified number of bytes. As a special case, `'0s'` means a single, empty string (while `'0c'` means 0 characters).

The `'p'` format character encodes a “Pascal string”, meaning a short variable-length string stored in a fixed number of bytes, given by the count. The first byte stored is the length of the string, or 255, whichever is smaller. The bytes of the string follow. If the string passed in to `pack()` is too long (longer than the count minus 1), only the leading `count-1` bytes of the string are stored. If the string is shorter than `count-1`, it is padded with null bytes so that exactly count bytes in all are used. Note that for `unpack()`, the `'p'` format character consumes count bytes, but that the string returned can never contain more than 255 characters.

For the `'P'` format character, the return value is a Python integer or long integer, depending on the size needed to hold a pointer when it has been cast to an integer type. A NULL pointer will always be returned as the Python integer `0`. When packing pointer-sized values, Python integer or long integer objects may be used. For example, the Alpha and Merced processors use 64-bit pointer values, meaning a Python long integer will be used to hold the pointer; other platforms use 32-bit pointers and will use a Python integer.

对于 `'?'` 格式字符，返回值为 `True` 或 `False`。 在打包时将会使用参数对象的逻辑值。 以本机或标准 bool 类型表示的 0 或 1 将被打包，任何非零值在解包时将为 `True`。

### 7.3.2.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 个字节的边界对齐:

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

这仅当本机大小和对齐方式生效时才会起作用；标准大小和对齐方式并不会强制进行任何对齐。

参见

模块 `array`

  被打包为二进制存储的同质数据。

模块 `xdrlib`

  打包和解包 XDR 数据。

## 7.3.3. 类

`struct` 模块还定义了以下类型：

class `struct.``Struct`(format)

  返回一个新的 Struct 对象，它会根据格式字符串 format 来写入和读取二进制数据。 一次性地创建 Struct 对象并调用其方法相比使用同样的格式调用 `struct` 函数更为高效，因为这样格式字符串只需被编译一次。

  2.5 新版功能.

  已编译的 Struct 对象支持以下方法和属性：

  `pack`(v1, v2, ...)

    Identical to the `pack()` function, using the compiled format. (`len(result)` will equal `self.size`.)

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

    等价于 `pack_into()` 函数，使用了已编译的格式。

  `unpack`(string)

    Identical to the `unpack()` function, using the compiled format. (`len(string)` must equal `self.size`).

  `unpack_from`(buffer, offset=0)

    Identical to the `unpack_from()` function, using the compiled format. (`len(buffer[offset:])` must be at least `self.size`).

  `format`

    用于构造此 Struct 对象的格式字符串。

  `size`

    The calculated size of the struct (and hence of the string) corresponding to `format`.