> **Источник:** https://python-all.ru/3.0/library/struct.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# `struct` – Интерпретация байтов как упакованных двоичных данных

Этот модуль выполняет преобразования между значениями Python и C-структурами, представленными в виде объектов [`bytes`](https://python-all.ru/3.0/library/functions.html#bytes). В нём используются *строки формата* (описаны ниже) как компактные описания расположения C-структур и предполагаемого преобразования в/из значений Python. Это может использоваться для обработки двоичных данных, хранящихся в файлах или полученных из сетевых соединений, среди прочих источников.

Модуль определяет следующие исключения и функции:

#### `[struct.error]exception struct.error`

Исключение, возникающее в различных ситуациях; аргумент – строка, описывающая, что не так.

#### `[struct.pack]struct.pack(fmt, v1, v2, ...)`

Возвращает объект bytes, содержащий значения

`v1, v2, ...`

, упакованные в соответствии с заданным форматом. Аргументы должны точно соответствовать значениям, требуемым форматом.

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

Упаковывает значения

`v1, v2, ...`

в соответствии с заданным форматом и записывает упакованные байты в записываемый

*buffer*

, начиная с

*offset*

. Обратите внимание, что смещение является обязательным аргументом.

#### `[struct.unpack]struct.unpack(fmt, bytes)`

Распаковывает байты (предположительно упакованные с помощью

`pack(fmt, ...)`

) в соответствии с заданным форматом. Результатом является кортеж, даже если он содержит ровно один элемент. Байты должны содержать ровно столько данных, сколько требуется форматом (

`len(bytes)`

должно равняться

`calcsize(fmt)`

).

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

Распаковывает

*buffer*

в соответствии с заданным форматом. Результатом является кортеж, даже если он содержит ровно один элемент.

*buffer*

должен содержать как минимум столько данных, сколько требуется форматом (

`len(buffer[offset:])`

должно быть не меньше

`calcsize(fmt)`

).

#### `[struct.calcsize]struct.calcsize(fmt)`

Возвращает размер структуры (и, соответственно, байтов), соответствующий заданному формату.

Символы формата имеют следующее значение; преобразование между значениями C и Python должно быть очевидным, учитывая их типы:

| Формат | Тип C | Python | Примечания |
| --- | --- | --- | --- |
| `x` | байт заполнения | нет значения |  |
| `c` | `char` | строка байт длиной 1 |  |
| `b` | `знаковый char` | целое число | (1) |
| `B` | `unsigned char` | целое число |  |
| `?` | `_Bool` | bool | (2) |
| `h` | `short` | целое число |  |
| `H` | `unsigned short` | целое число |  |
| `i` | `int` | целое число |  |
| `I` | `unsigned int` | целое число |  |
| `l` | `long` | целое число |  |
| `L` | `unsigned long` | целое число |  |
| `q` | `long long` | целое число | (3) |
| `Q` | `unsigned long long` | целое число | (3) |
| `f` | `float` | float |  |
| `d` | `double` | float |  |
| `s` | `char[]` | байты | (1) |
| `p` | `char[]` | байты | (1) |
| `P` | `void *` | целое число |  |

Примечания:

1. Коды преобразования `c`, `s` и `p` работают с объектами [`bytes`](https://python-all.ru/3.0/library/functions.html#bytes), но упаковка с этими кодами также поддерживает объекты [`str`](https://python-all.ru/3.0/library/functions.html#str), которые кодируются с использованием UTF-8.
2. Код преобразования `'?'` соответствует типу `_Bool`, определённому в C99. Если этот тип недоступен, он имитируется с помощью `char`. В стандартном режиме он всегда представлен одним байтом.
3. Коды преобразования `'q'` и `'Q'` доступны в родном режиме, только если компилятор C платформы поддерживает C `long long` или, в Windows, `__int64`. Они всегда доступны в стандартных режимах.

Символу формата может предшествовать целочисленный счетчик повторений. Например, строка формата `'4h'` означает то же самое, что и `'hhhh'`.

Пробельные символы между форматами игнорируются; однако счётчик и его формат не должны содержать пробелов.

Для символа формата `'s'` количество интерпретируется как длина строки в байтах, а не как количество повторений, как для других символов формата; например, `'10s'` означает одну строку длиной 10 байт, тогда как `'10c'` означает 10 символов. При упаковке строка усекается или дополняется нулевыми байтами по мере необходимости, чтобы соответствовать заданной длине. При распаковке результирующий объект bytes всегда содержит ровно указанное количество байт. В частном случае `'0s'` означает одну пустую строку (а `'0c'` означает 0 символов).

Символ формата `'p'` кодирует «строку Паскаля», то есть короткую строку переменной длины, хранящуюся в фиксированном количестве байтов. Значение count – это общее количество сохраняемых байтов. Первый сохраняемый байт – это длина строки или 255, в зависимости от того, что меньше. Затем следуют байты строки. Если строка, переданная в [`pack()`](https://python-all.ru/3.0/library/struct.html#struct.pack), слишком длинная (длиннее, чем count минус 1), сохраняются только первые count-1 байтов строки. Если строка короче count-1, она дополняется нулевыми байтами, чтобы в итоге было использовано ровно count байтов. Обратите внимание, что для [`unpack()`](https://python-all.ru/3.0/library/struct.html#struct.unpack) символ формата `'p'` потребляет count байтов, но возвращаемая строка никогда не может содержать более 255 байтов.

Для символа формата `'?'` возвращаемым значением является либо [`True`](https://python-all.ru/3.0/library/constants.html#True), либо [`False`](https://python-all.ru/3.0/library/constants.html#False). При упаковке используется истинностное значение объекта-аргумента. Будет упакован либо 0, либо 1 в нативном или стандартном представлении bool, а при распаковке любое ненулевое значение станет True.

По умолчанию числа C представляются в собственном формате и порядке байтов машины и выравниваются должным образом путём пропуска байтов заполнения при необходимости (в соответствии с правилами, используемыми компилятором C).

В качестве альтернативы, первый символ строки формата может использоваться для указания порядка байтов, размера и выравнивания упакованных данных, как показано в следующей таблице:

| Символ | Порядок байтов | Размер и выравнивание |
| --- | --- | --- |
| `@` | собственный | собственный |
| `=` | собственный | стандартный |
| `<` | little-endian | стандартный |
| `>` | big-endian | стандартный |
| `!` | сетевой порядок байт (= big-endian) | стандартный |

Если первый символ не один из этих, предполагается `'@'`.

Родной порядок байт – big-endian или little-endian, в зависимости от хост-системы. Например, процессоры Motorola и Sun – big-endian, а Intel и DEC – little-endian.

Собственный размер и выравнивание определяются с помощью выражения `sizeof` компилятора C. Это всегда сочетается с собственным порядком байтов.

Стандартные размеры и выравнивание: для любого типа не требуется выравнивание (поэтому необходимо использовать байты заполнения); `short` занимает 2 байта; `int` и `long` – 4 байта; `long long` (`__int64` в Windows) – 8 байт; `float` и `double` – 32-битные и 64-битные числа с плавающей точкой IEEE соответственно. `_Bool` занимает 1 байт.

Обратите внимание на различие между `'@'` и `'='`: оба используют собственный порядок байт, но размер и выравнивание второго стандартизированы.

Форма `'!'` доступна для тех несчастных, кто утверждает, что не может запомнить, является ли сетевой порядок байтов big-endian или little-endian.

Нет способа указать несобственный порядок байт (принудительную перестановку байт); используйте соответствующий выбор из `'<'` или `'>'`.

Символ формата `'P'` доступен только для родного порядка байт (выбранного по умолчанию или с помощью символа порядка байт `'@'`). Символ порядка байт `'='` выбирает порядок little-endian или big-endian в зависимости от хост-системы. Модуль struct не интерпретирует это как родной порядок, поэтому формат `'P'` недоступен.

Примеры (все используют родной порядок байт, размеры и выравнивание, на big-endian машине):

```python
>>> 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
```

Подсказка: чтобы выровнять конец структуры под требование выравнивания конкретного типа, завершите формат кодом этого типа с нулевым счётчиком повторений. Например, формат `'llh0l'` задаёт два байта заполнения в конце (в предположении, что long выравниваются по 4-байтовым границам). Это работает только в режиме родных размеров и выравнивания; в стандартном режиме выравнивание не навязывается.

Распакованные поля можно именовать, присваивая их переменным или оборачивая результат в именованный кортеж:

```python
>>> 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)
```

> **См. также**
>
> **Модуль [`array`](https://python-all.ru/3.0/library/array.html#module-array)**
>
> Упакованное бинарное хранение однородных данных.
>
> **Модуль [`xdrlib`](https://python-all.ru/3.0/library/xdrlib.html#module-xdrlib)**
>
> Упаковка и распаковка данных XDR.

## Объекты Struct

Модуль `struct` также определяет следующий тип:

#### `[struct.Struct]class struct.Struct(format)`

Возвращает новый объект Struct, который записывает и читает двоичные данные в соответствии со строкой формата *format*. Создание объекта Struct один раз и вызов его методов эффективнее, чем вызов функций `struct` с тем же форматом, поскольку строку формата нужно скомпилировать только один раз.

Скомпилированные объекты Struct поддерживают следующие методы и атрибуты:

#### `[struct.Struct.pack]pack(v1, v2, ...)`

Идентично функции

[`pack()`](https://python-all.ru/3.0/library/struct.html#struct.pack)

с использованием скомпилированного формата. (

`len(result)`

будет равно

`self.size`

.)

#### `[struct.Struct.pack_into]pack_into(buffer, offset, v1, v2, ...)`

Идентично функции

[`pack_into()`](https://python-all.ru/3.0/library/struct.html#struct.pack_into)

с использованием скомпилированного формата.

#### `[struct.Struct.unpack]unpack(bytes)`

Идентична функции

[`unpack()`](https://python-all.ru/3.0/library/struct.html#struct.unpack)

, использующей скомпилированный формат. (

`len(bytes)`

должно быть равно

`self.size`

).

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

Идентично функции

[`unpack_from()`](https://python-all.ru/3.0/library/struct.html#struct.unpack_from)

с использованием скомпилированного формата. (

`len(buffer[offset:])`

должно быть не менее

`self.size`

).

#### `[struct.Struct.format]format`

Строка форматирования, используемая для создания этого объекта Struct.

#### `[struct.Struct.size]size`

Вычисленный размер структуры (и, соответственно, размер байтовой строки), соответствующий

[`format`](https://python-all.ru/3.0/library/functions.html#format)

.
