struct.md
1> **Источник:** https://python-all.ru/3.8/library/struct.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [`struct`](https://python-all.ru/3.8/library/struct.html#module-struct) – Интерпретация байтов как упакованных двоичных данных89**Исходный код:** [Lib/struct.py](https://python-all.ru/src/3.8/Lib/struct.py)1011---1213Этот модуль выполняет преобразования между значениями Python и C-структурами, представленными в виде объектов [`bytes`](https://python-all.ru/3.8/library/stdtypes.html#bytes) Python. Он может использоваться для обработки двоичных данных, хранящихся в файлах или получаемых из сетевых соединений, а также из других источников. В нём используются [строки формата](https://python-all.ru/3.8/library/struct.html#struct-format-strings) как компактное описание расположения C-структур и предполагаемого преобразования в/из значений Python.1415> **Примечание**16>17> По умолчанию результат упаковки заданной C-структуры включает байты заполнения для сохранения правильного выравнивания для задействованных C-типов; аналогично, выравнивание учитывается при распаковке. Такое поведение выбрано, чтобы байты упакованной структуры точно соответствовали расположению в памяти соответствующей C-структуры. Для обработки платформенно-независимых форматов данных или пропуска неявных байтов заполнения используйте `standard` размер и выравнивание вместо `native` размера и выравнивания: см. [Порядок байтов, размер и выравнивание](https://python-all.ru/3.8/library/struct.html#struct-alignment) для подробностей.1819Некоторые функции [`struct`](https://python-all.ru/3.8/library/struct.html#module-struct) (и методы [`Struct`](https://python-all.ru/3.8/library/struct.html#struct.Struct)) принимают аргумент *buffer* (буфер). Он ссылается на объекты, реализующие [протокол буфера](https://python-all.ru/3.8/c-api/buffer.html#bufferobjects) и предоставляющие буфер для чтения или чтения-записи. Наиболее распространённые типы, используемые для этой цели, – [`bytes`](https://python-all.ru/3.8/library/stdtypes.html#bytes) и [`bytearray`](https://python-all.ru/3.8/library/stdtypes.html#bytearray), но многие другие типы, которые можно рассматривать как массив байтов, реализуют протокол буфера, поэтому их можно читать/заполнять без дополнительного копирования из объекта [`bytes`](https://python-all.ru/3.8/library/stdtypes.html#bytes).2021## Функции и исключения2223Модуль определяет следующие исключения и функции:2425#### `exception struct.error`2627Исключение, вызываемое в различных ситуациях; аргумент – строка, описывающая, что не так.2829#### `struct.pack(format, v1, v2, ...)`3031Возвращает объект bytes, содержащий значения *v1*, *v2*, …, упакованные в соответствии со строкой формата *format*. Аргументы должны точно соответствовать значениям, требуемым форматом.3233#### `struct.pack_into(format, buffer, offset, v1, v2, ...)`3435Упаковывает значения *v1*, *v2*, … в соответствии со строкой формата *format* и записывает упакованные байты в буфер *buffer*, начиная с позиции *offset*. Обратите внимание, что *offset* – обязательный аргумент.3637#### `struct.unpack(format, buffer)`3839Распаковывает из буфера *buffer* (предположительно упакованного с помощью `pack(format, ...)`) в соответствии со строкой формата *format*. Результат – кортеж, даже если он содержит ровно один элемент. Размер буфера в байтах должен соответствовать размеру, требуемому форматом, отражённому [`calcsize()`](https://python-all.ru/3.8/library/struct.html#struct.calcsize).4041#### `struct.unpack_from(format, buffer, offset=0)`4243Распаковывает из *buffer*, начиная с позиции *offset*, в соответствии со строкой формата *format*. Результат – кортеж, даже если он содержит ровно один элемент. Размер буфера в байтах, начиная с позиции *offset*, должен быть не меньше размера, требуемого форматом, отражённого [`calcsize()`](https://python-all.ru/3.8/library/struct.html#struct.calcsize).4445#### `struct.iter_unpack(format, buffer)`4647Итеративно распаковывает данные из буфера *buffer* в соответствии со строкой формата *format*. Эта функция возвращает итератор, который будет читать из буфера блоки одинакового размера, пока всё его содержимое не будет исчерпано. Размер буфера в байтах должен быть кратен размеру, требуемому форматом, как указано в [`calcsize()`](https://python-all.ru/3.8/library/struct.html#struct.calcsize).4849Каждая итерация возвращает кортеж, как указано в строке формата.5051Новое в версии 3.4.5253#### `struct.calcsize(format)`5455Возвращает размер структуры (и, следовательно, объекта bytes, полученного с помощью `pack(format, ...)`), соответствующий строке формата *format*.5657## Строки формата5859Строки формата – это механизм, используемый для указания ожидаемого расположения данных при упаковке и распаковке. Они составляются из [символов формата](https://python-all.ru/3.8/library/struct.html#format-characters), которые задают тип упаковываемых/распаковываемых данных. Кроме того, существуют специальные символы для управления [порядком байтов, размером и выравниванием](https://python-all.ru/3.8/library/struct.html#struct-alignment).6061### Порядок байтов, размер и выравнивание6263По умолчанию типы C представляются в собственном формате и порядке байтов машины и правильно выравниваются путём пропуска байтов заполнения при необходимости (в соответствии с правилами, используемыми компилятором C).6465В качестве альтернативы, первый символ строки формата может использоваться для указания порядка байтов, размера и выравнивания упакованных данных, как показано в следующей таблице:6667| Символ | Порядок байтов | Размер | Выравнивание |68| --- | --- | --- | --- |69| `@` | собственный | собственный | собственный |70| `=` | собственный | стандартный | нет |71| `<` | little-endian | стандартный | нет |72| `>` | big-endian | стандартный | нет |73| `!` | сетевой порядок байт (= big-endian) | стандартный | нет |7475Если первый символ не один из этих, предполагается `'@'`.7677Собственный порядок байтов может быть big-endian или little-endian в зависимости от хост-системы. Например, Intel x86 и AMD64 (x86-64) используют little-endian; Motorola 68000 и PowerPC G5 – big-endian; ARM и Intel Itanium поддерживают переключаемый порядок байтов (bi-endian). Используйте `sys.byteorder` для проверки порядка байтов вашей системы.7879Собственный размер и выравнивание определяются с помощью выражения `sizeof` компилятора C. Это всегда используется вместе с собственным порядком байт.8081Стандартный размер зависит только от символа формата; см. таблицу в разделе [Символы формата](https://python-all.ru/3.8/library/struct.html#format-characters).8283Обратите внимание на различие между `'@'` и `'='`: оба используют собственный порядок байт, но размер и выравнивание второго стандартизированы.8485Форма `'!'` представляет сетевой порядок байт, который всегда является big-endian, как определено в [IETF RFC 1700](https://python-all.ru/3.8/library/struct.html).8687Нет способа указать несобственный порядок байт (принудительную перестановку байт); используйте соответствующий выбор из `'<'` или `'>'`.8889Примечания:90911. Заполнение автоматически добавляется только между последовательными членами структуры. Начало и конец закодированной структуры не дополняются.922. Заполнение не добавляется при использовании несобственного размера и выравнивания, например, с ‘\<’, ‘\>’, ‘=’ и ‘!’.933. Чтобы выровнять конец структуры по требованию выравнивания конкретного типа, завершите формат кодом этого типа с нулевым количеством повторений. См. [Примеры](https://python-all.ru/3.8/library/struct.html#struct-examples).9495### Символы формата9697Символы формата имеют следующее значение; преобразование между значениями C и Python должно быть очевидным, исходя из их типов. Столбец «Стандартный размер» указывает размер упакованного значения в байтах при использовании стандартного размера; то есть когда строка формата начинается с одного из `'<'`, `'>'`, `'!'` или `'='`. При использовании собственного размера размер упакованного значения зависит от платформы.9899| Формат | Тип C | Тип Python | Стандартный размер | Примечания |100| --- | --- | --- | --- | --- |101| `x` | байт заполнения | нет значения | | |102| `c` | `char` | строка байт длиной 1 | 1 | |103| `b` | `signed char` | целое число | 1 | (1), (2) |104| `B` | `unsigned char` | целое число | 1 | (2) |105| `?` | `_Bool` | bool | 1 | (1) |106| `h` | `short` | целое число | 2 | (2) |107| `H` | `unsigned short` | целое число | 2 | (2) |108| `i` | `int` | целое число | 4 | (2) |109| `I` | `unsigned int` | целое число | 4 | (2) |110| `l` | `long` | целое число | 4 | (2) |111| `L` | `unsigned long` | целое число | 4 | (2) |112| `q` | `long long` | целое число | 8 | (2) |113| `Q` | `unsigned long long` | целое число | 8 | (2) |114| `n` | `ssize_t` | целое число | | (3) |115| `N` | `size_t` | целое число | | (3) |116| `e` | (6) | float | 2 | (4) |117| `f` | `float` | float | 4 | (4) |118| `d` | `double` | float | 8 | (4) |119| `s` | `char[]` | bytes | | |120| `p` | `char[]` | bytes | | |121| `P` | `void *` | целое число | | (5) |122123Изменено в версии 3.3: Добавлена поддержка форматов `'n'` и `'N'`.124125Изменено в версии 3.6: Добавлена поддержка формата `'e'`.126127Примечания:1281291. Код преобразования `'?'` соответствует типу `_Bool`, определённому в стандарте C99. Если этот тип недоступен, он эмулируется с помощью `char`. В стандартном режиме он всегда представлен одним байтом.1302. При попытке упаковать нецелое число с использованием любого из кодов преобразования целых чисел, если нецелое число имеет метод [`__index__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__index__), то этот метод вызывается для преобразования аргумента в целое число перед упаковкой.131132 Изменено в версии 3.2: Использование метода [`__index__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__index__) для нецелых чисел появилось в версии 3.2.1333. Коды преобразования `'n'` и `'N'` доступны только для родного размера (выбранного по умолчанию или с символом порядка байтов `'@'`). Для стандартного размера можно использовать любой из других целочисленных форматов, который подходит для приложения.1344. Для кодов преобразования `'f'`, `'d'` и `'e'` упакованное представление использует форматы IEEE 754 binary32, binary64 или binary16 (для `'f'`, `'d'` или `'e'` соответственно), независимо от формата чисел с плавающей запятой, используемого платформой.1355. Символ формата `'P'` доступен только для родного порядка байтов (выбранного по умолчанию или с символом порядка байтов `'@'`). Символ порядка байтов `'='` выбирает порядок little- или big-endian в зависимости от хост-системы. Модуль struct не интерпретирует это как родной порядок, поэтому формат `'P'` недоступен.1366. Тип IEEE 754 binary16 «половинной точности» был введён в редакции [стандарта IEEE 754](https://python-all.ru/3.8/library/struct.html) 2008 года. Он имеет знаковый бит, 5-битную экспоненту и 11-битную точность (10 бит хранятся явно) и может представлять числа от примерно `6.1e-05` до `6.5e+04` с полной точностью. Этот тип не получил широкой поддержки в компиляторах C: на типичной машине unsigned short можно использовать для хранения, но не для математических операций. См. страницу Википедии о [формате чисел с плавающей запятой половинной точности](https://python-all.ru/3.8/library/struct.html) для получения дополнительной информации.137138Символу формата может предшествовать целочисленный счётчик повторений. Например, строка формата `'4h'` означает то же самое, что и `'hhhh'`.139140Пробельные символы между форматами игнорируются; однако счётчик и его формат не должны содержать пробелов.141142Для символа формата `'s'` счётчик интерпретируется как длина строки в байтах, а не как количество повторений, как для других символов формата; например, `'10s'` означает одну 10-байтовую строку, а `'10c'` – 10 символов. Если счётчик не указан, по умолчанию он равен 1. При упаковке строка усекается или дополняется нулевыми байтами по мере необходимости, чтобы соответствовать размеру. При распаковке результирующий объект bytes всегда имеет ровно указанное количество байт. В особом случае `'0s'` означает одну пустую строку (а `'0c'` – 0 символов).143144При упаковке значения `x` с использованием одного из целочисленных форматов (`'b'`, `'B'`, `'h'`, `'H'`, `'i'`, `'I'`, `'l'`, `'L'`, `'q'`, `'Q'`), если `x` выходит за допустимый диапазон для этого формата, то вызывается [`struct.error`](https://python-all.ru/3.8/library/struct.html#struct.error).145146Изменено в версии 3.1: В версии 3.0 некоторые целочисленные форматы выполняли перенос значений за пределами диапазона и вызывали [`DeprecationWarning`](https://python-all.ru/3.8/library/exceptions.html#DeprecationWarning) вместо [`struct.error`](https://python-all.ru/3.8/library/struct.html#struct.error).147148Символ форматирования `'p'` кодирует «строку Паскаля» – короткую строку переменной длины, хранящуюся в *фиксированном количестве байт*, задаваемом счётчиком. Первым байтом хранится длина строки или 255 (выбирается меньшее). Затем следуют байты строки. Если строка, переданная в [`pack()`](https://python-all.ru/3.8/library/struct.html#struct.pack), слишком длинна (длиннее, чем счётчик минус 1), сохраняются только первые `count-1` байт строки. Если строка короче `count-1`, она дополняется нулевыми байтами так, чтобы всего было использовано ровно счётчик байт. Обратите внимание, что для [`unpack()`](https://python-all.ru/3.8/library/struct.html#struct.unpack) символ форматирования `'p'` потребляет `count` байт, но возвращаемая строка никогда не может содержать более 255 байт.149150Для символа формата `'?'` возвращаемое значение – [`True`](https://python-all.ru/3.8/library/constants.html#True) или [`False`](https://python-all.ru/3.8/library/constants.html#False). При упаковке используется истинностное значение объекта-аргумента. Будет упакован либо 0, либо 1 в родном или стандартном представлении bool, и любое ненулевое значение будет `True` при распаковке.151152### Примеры153154> **Примечание**155>156> Все примеры предполагают собственный порядок байтов, размер и выравнивание на машине с big-endian.157158Простой пример упаковки/распаковки трёх целых чисел:159160```python161>>> from struct import *162>>> pack('hhl', 1, 2, 3)163b'\x00\x01\x00\x02\x00\x00\x00\x03'164>>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03')165(1, 2, 3)166>>> calcsize('hhl')1678168```169170Распакованные поля можно именовать, присваивая их переменным или оборачивая результат в именованный кортеж:171172```python173>>> record = b'raymond \x32\x12\x08\x01\x08'174>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)175176>>> from collections import namedtuple177>>> Student = namedtuple('Student', 'name serialnum school gradelevel')178>>> Student._make(unpack('<10sHHb', record))179Student(name=b'raymond ', serialnum=4658, school=264, gradelevel=8)180```181182Порядок символов формата может влиять на размер, поскольку заполнение, необходимое для удовлетворения требований выравнивания, отличается:183184```python185>>> pack('ci', b'*', 0x12131415)186b'*\x00\x00\x00\x12\x13\x14\x15'187>>> pack('ic', 0x12131415, b'*')188b'\x12\x13\x14\x15*'189>>> calcsize('ci')1908191>>> calcsize('ic')1925193```194195Следующий формат `'llh0l'` указывает два байта заполнения в конце, предполагая, что значения типа long выровнены по границе в 4 байта:196197```python198>>> pack('llh0l', 1, 2, 3)199b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'200```201202Это работает только при использовании собственного размера и выравнивания; стандартный размер и выравнивание не обеспечивают никакого выравнивания.203204> **См. также**205>206> **Модуль [`array`](https://python-all.ru/3.8/library/array.html#module-array)**207>208> Упакованное бинарное хранение однородных данных.209>210> **Модуль [`xdrlib`](https://python-all.ru/3.8/library/xdrlib.html#module-xdrlib)**211>212> Упаковка и распаковка данных XDR.213214## Классы215216Модуль [`struct`](https://python-all.ru/3.8/library/struct.html#module-struct) также определяет следующий тип:217218#### `class struct.Struct(format)`219220Возвращает новый объект Struct, который записывает и читает двоичные данные в соответствии со строкой формата *format*. Создание объекта Struct один раз и вызов его методов эффективнее, чем вызов функций [`struct`](https://python-all.ru/3.8/library/struct.html#module-struct) с тем же форматом, поскольку строку формата нужно скомпилировать только один раз.221222> **Примечание**223>224> Скомпилированные версии последних строк формата, переданных в [`Struct`](https://python-all.ru/3.8/library/struct.html#struct.Struct) и функции уровня модуля, кэшируются, поэтому программам, использующим лишь несколько строк формата, не нужно беспокоиться о повторном использовании одного экземпляра [`Struct`](https://python-all.ru/3.8/library/struct.html#struct.Struct).225226Скомпилированные объекты Struct поддерживают следующие методы и атрибуты:227228#### `pack(v1, v2, ...)`229230Идентично функции [`pack()`](https://python-all.ru/3.8/library/struct.html#struct.pack), использует скомпилированный формат. (`len(result)` будет равно [`size`](https://python-all.ru/3.8/library/struct.html#struct.Struct.size).)231232#### `pack_into(buffer, offset, v1, v2, ...)`233234Идентично функции [`pack_into()`](https://python-all.ru/3.8/library/struct.html#struct.pack_into), использует скомпилированный формат.235236#### `unpack(buffer)`237238Идентично функции [`unpack()`](https://python-all.ru/3.8/library/struct.html#struct.unpack), использует скомпилированный формат. Размер буфера в байтах должен быть равен [`size`](https://python-all.ru/3.8/library/struct.html#struct.Struct.size).239240#### `unpack_from(buffer, offset=0)`241242Идентично функции [`unpack_from()`](https://python-all.ru/3.8/library/struct.html#struct.unpack_from), использует скомпилированный формат. Размер буфера в байтах, начиная с позиции *offset*, должен быть не менее [`size`](https://python-all.ru/3.8/library/struct.html#struct.Struct.size).243244#### `iter_unpack(buffer)`245246Идентично функции [`iter_unpack()`](https://python-all.ru/3.8/library/struct.html#struct.iter_unpack), использует скомпилированный формат. Размер буфера в байтах должен быть кратен [`size`](https://python-all.ru/3.8/library/struct.html#struct.Struct.size).247248Новое в версии 3.4.249250#### `format`251252Строка форматирования, используемая для создания этого объекта Struct.253254Изменено в версии 3.7: Тип строки форматирования теперь [`str`](https://python-all.ru/3.8/library/stdtypes.html#str) вместо [`bytes`](https://python-all.ru/3.8/library/stdtypes.html#bytes).255256#### `size`257258Вычисленный размер структуры (и, следовательно, объекта bytes, создаваемого методом [`pack()`](https://python-all.ru/3.8/library/struct.html#struct.pack)), соответствующий [`format`](https://python-all.ru/3.8/library/functions.html#format).259