Документация Python неофициальный перевод

struct.md

235 строк · 24.0 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/2.7/library/struct.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 7.3. [`struct`](https://python-all.ru/2.7/library/struct.html#module-struct) – Интерпретация строк как упакованных двоичных данных89Этот модуль выполняет преобразование между значениями Python и структурами C, представленными в виде строк Python. Его можно использовать для обработки двоичных данных, хранящихся в файлах, полученных из сетевых соединений и других источников. Для компактного описания структуры C-структур и предполагаемого преобразования в/из значений Python в нём используются [строки формата](https://python-all.ru/2.7/library/struct.html#struct-format-strings).1011> **Примечание**12>13> По умолчанию результат упаковки заданной C-структуры включает байты заполнения для сохранения правильного выравнивания для задействованных C-типов; аналогично, выравнивание учитывается при распаковке. Такое поведение выбрано, чтобы байты упакованной структуры точно соответствовали расположению в памяти соответствующей C-структуры. Для обработки платформенно-независимых форматов данных или пропуска неявных байтов заполнения используйте `standard` размер и выравнивание вместо `native` размера и выравнивания: см. [Порядок байтов, размер и выравнивание](https://python-all.ru/2.7/library/struct.html#struct-alignment) для подробностей.1415## 7.3.1. Функции и исключения1617Модуль определяет следующие исключения и функции:1819#### `exception struct.error`2021Исключение, вызываемое в различных ситуациях; аргумент – строка, описывающая, что не так.2223#### `struct.pack(fmt, v1, v2, ...)`2425Возвращает строку, содержащую значения `v1, v2, ...`, упакованные согласно заданному формату. Аргументы должны точно соответствовать значениям, требуемым форматом.2627#### `struct.pack_into(fmt, buffer, offset, v1, v2, ...)`2829Упаковывает значения `v1, v2, ...` согласно заданному формату и записывает упакованные байты в *записываемый буфер*, начиная с *смещения*. Обратите внимание, что смещение является обязательным аргументом.3031Новое в версии 2.5.3233#### `struct.unpack(fmt, string)`3435Распаковывает строку (предположительно упакованную с помощью `pack(fmt, ...)`) в соответствии с заданным форматом. Результатом является кортеж, даже если он содержит ровно один элемент. Строка должна содержать ровно столько данных, сколько требует формат (`len(string)` должно равняться `calcsize(fmt)`).3637#### `struct.unpack_from(fmt, buffer[, offset=0])`3839Распаковывает *буфер* в соответствии с заданным форматом. Результатом является кортеж, даже если он содержит ровно один элемент. *Буфер* должен содержать как минимум столько данных, сколько требует формат (`len(buffer[offset:])` должно быть не менее `calcsize(fmt)`).4041Новое в версии 2.5.4243#### `struct.calcsize(fmt)`4445Возвращает размер структуры (и, следовательно, строки), соответствующий заданному формату.4647## 7.3.2. Строки формата4849Строки формата – это механизм, используемый для указания ожидаемого расположения данных при упаковке и распаковке. Они составляются из [символов формата](https://python-all.ru/2.7/library/struct.html#format-characters), которые задают тип упаковываемых/распаковываемых данных. Кроме того, существуют специальные символы для управления [порядком байтов, размером и выравниванием](https://python-all.ru/2.7/library/struct.html#struct-alignment).5051### 7.3.2.1. Порядок байтов, размер и выравнивание5253По умолчанию типы C представляются в собственном формате и порядке байтов машины и правильно выравниваются путём пропуска байтов заполнения при необходимости (в соответствии с правилами, используемыми компилятором C).5455В качестве альтернативы, первый символ строки формата может использоваться для указания порядка байтов, размера и выравнивания упакованных данных, как показано в следующей таблице:5657| Символ | Порядок байтов | Размер | Выравнивание |58| --- | --- | --- | --- |59| `@` | собственный | собственный | собственный |60| `=` | собственный | стандартный | нет |61| `<` | little-endian | стандартный | нет |62| `>` | big-endian | стандартный | нет |63| `!` | сетевой порядок байт (= big-endian) | стандартный | нет |6465Если первый символ не один из этих, предполагается `'@'`.6667Собственный порядок байтов может быть big-endian или little-endian в зависимости от хост-системы. Например, Intel x86 и AMD64 (x86-64) используют little-endian; Motorola 68000 и PowerPC G5 – big-endian; ARM и Intel Itanium поддерживают переключаемый порядок байтов (bi-endian). Используйте `sys.byteorder` для проверки порядка байтов вашей системы.6869Собственный размер и выравнивание определяются с помощью выражения `sizeof` компилятора C. Это всегда используется вместе с собственным порядком байт.7071Стандартный размер зависит только от символа формата; см. таблицу в разделе [Символы формата](https://python-all.ru/2.7/library/struct.html#format-characters).7273Обратите внимание на различие между `'@'` и `'='`: оба используют собственный порядок байт, но размер и выравнивание второго стандартизированы.7475Форма `'!'` доступна для тех несчастных, кто утверждает, что не может запомнить, является ли сетевой порядок байтов big-endian или little-endian.7677Нет способа указать несобственный порядок байт (принудительную перестановку байт); используйте соответствующий выбор из `'<'` или `'>'`.7879Примечания:80811. Заполнение автоматически добавляется только между последовательными членами структуры. Начало и конец закодированной структуры не дополняются.822. Заполнение не добавляется при использовании несобственного размера и выравнивания, например, с ‘\<’, ‘\>’, ‘=’ и ‘!’.833. Чтобы выровнять конец структуры по требованию выравнивания конкретного типа, завершите формат кодом этого типа с нулевым количеством повторений. См. [Примеры](https://python-all.ru/2.7/library/struct.html#struct-examples).8485### 7.3.2.2. Символы формата8687Символы формата имеют следующее значение; преобразование между значениями C и Python должно быть очевидным, исходя из их типов. Столбец «Стандартный размер» указывает размер упакованного значения в байтах при использовании стандартного размера; то есть когда строка формата начинается с одного из `'<'`, `'>'`, `'!'` или `'='`. При использовании собственного размера размер упакованного значения зависит от платформы.8889| Формат | Тип C | Тип Python | Стандартный размер | Примечания |90| --- | --- | --- | --- | --- |91| `x` | байт заполнения | нет значения |  |  |92| `c` | `char` | строка длиной 1 | 1 |  |93| `b` | `signed char` | целое число | 1 | (3) |94| `B` | `unsigned char` | целое число | 1 | (3) |95| `?` | `_Bool` | bool | 1 | (1) |96| `h` | `short` | целое число | 2 | (3) |97| `H` | `unsigned short` | целое число | 2 | (3) |98| `i` | `int` | целое число | 4 | (3) |99| `I` | `unsigned int` | целое число | 4 | (3) |100| `l` | `long` | целое число | 4 | (3) |101| `L` | `unsigned long` | целое число | 4 | (3) |102| `q` | `long long` | целое число | 8 | (2), (3) |103| `Q` | `unsigned long long` | целое число | 8 | (2), (3) |104| `f` | `float` | float | 4 | (4) |105| `d` | `double` | float | 8 | (4) |106| `s` | `char[]` | строка |  |  |107| `p` | `char[]` | строка |  |  |108| `P` | `void *` | целое число |  | (5), (3) |109110Примечания:1111121. Код преобразования `'?'` соответствует типу `_Bool`, определённому в стандарте C99. Если этот тип недоступен, он эмулируется с помощью `char`. В стандартном режиме он всегда представлен одним байтом.113114   Новое в версии 2.6.1152. Коды преобразования `'q'` и `'Q'` доступны в родном режиме только в том случае, если компилятор C платформы поддерживает C `long long` или, в Windows, `__int64`. Они всегда доступны в стандартных режимах.116117   Новое в версии 2.2.1183. При попытке упаковать нецелое число с помощью любого из кодов преобразования целых чисел, если нецелое число имеет метод [`__index__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__index__), то этот метод вызывается для преобразования аргумента в целое число перед упаковкой. Если метод [`__index__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__index__) не существует или вызов [`__index__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__index__) вызывает [`TypeError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.TypeError), то используется метод [`__int__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__int__). Однако использование [`__int__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__int__) устарело и будет вызывать [`DeprecationWarning`](https://python-all.ru/2.7/library/exceptions.html#exceptions.DeprecationWarning).119120   Изменено в версии 2.7: Использование метода [`__index__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__index__) для нецелых чисел является новым в версии 2.7.121122   Изменено в версии 2.7: До версии 2.7 не все коды преобразования целых чисел использовали метод [`__int__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__int__) для преобразования, и [`DeprecationWarning`](https://python-all.ru/2.7/library/exceptions.html#exceptions.DeprecationWarning) вызывалось только для аргументов типа float.1234. Для кодов преобразования `'f'` и `'d'` упакованное представление использует формат IEEE 754 binary32 (для `'f'`) или binary64 (для `'d'`), независимо от формата чисел с плавающей запятой, используемого платформой.1245. Символ формата `'P'` доступен только для родного порядка байтов (выбранного по умолчанию или с символом порядка байтов `'@'`). Символ порядка байтов `'='` выбирает порядок little- или big-endian в зависимости от хост-системы. Модуль struct не интерпретирует это как родной порядок, поэтому формат `'P'` недоступен.125126Символу формата может предшествовать целочисленный счётчик повторений. Например, строка формата `'4h'` означает то же самое, что и `'hhhh'`.127128Пробельные символы между форматами игнорируются; однако счётчик и его формат не должны содержать пробелов.129130Для символа формата `'s'` количество интерпретируется как размер строки, а не как число повторений, как для других символов формата; например, `'10s'` означает одну 10-байтовую строку, тогда как `'10c'` означает 10 символов. Если количество не указано, по умолчанию оно равно 1. При упаковке строка усекается или дополняется нулевыми байтами по мере необходимости, чтобы она поместилась. При распаковке результирующая строка всегда содержит ровно указанное количество байтов. В особом случае `'0s'` означает одну пустую строку (тогда как `'0c'` означает 0 символов).131132Символ формата `'p'` кодирует «строку Pascal», то есть короткую строку переменной длины, хранящуюся в *фиксированном числе байтов*, заданном количеством. Первым сохраняемым байтом является длина строки или 255, в зависимости от того, что меньше. Затем следуют байты строки. Если строка, переданная в [`pack()`](https://python-all.ru/2.7/library/struct.html#struct.pack), слишком длинная (длиннее, чем count минус 1), сохраняются только первые `count-1` байтов строки. Если строка короче `count-1`, она дополняется нулевыми байтами так, чтобы в итоге было использовано ровно count байтов. Обратите внимание, что для [`unpack()`](https://python-all.ru/2.7/library/struct.html#struct.unpack) символ формата `'p'` потребляет count байтов, но возвращаемая строка никогда не может содержать более 255 символов.133134Для символа формата `'P'` возвращаемым значением является целое число Python (int) или длинное целое (long) в зависимости от размера, необходимого для хранения указателя после приведения к целочисленному типу. *Нулевой* указатель (NULL) всегда возвращается как целое число Python `0`. При упаковке значений размером с указатель можно использовать объекты int или long. Например, процессоры Alpha и Merced используют 64-битные указатели, поэтому для хранения указателя будет использоваться длинное целое Python; на других платформах используются 32-битные указатели, и будет использоваться целое Python.135136Для символа формата `'?'` возвращаемое значение – [`True`](https://python-all.ru/2.7/library/constants.html#True) или [`False`](https://python-all.ru/2.7/library/constants.html#False). При упаковке используется истинностное значение объекта-аргумента. Будет упакован либо 0, либо 1 в родном или стандартном представлении bool, и любое ненулевое значение будет `True` при распаковке.137138### 7.3.2.3. Примеры139140> **Примечание**141>142> Все примеры предполагают собственный порядок байтов, размер и выравнивание на машине с big-endian.143144Простой пример упаковки/распаковки трёх целых чисел:145146```python147>>> from struct import *148>>> pack('hhl', 1, 2, 3)149'\x00\x01\x00\x02\x00\x00\x00\x03'150>>> unpack('hhl', '\x00\x01\x00\x02\x00\x00\x00\x03')151(1, 2, 3)152>>> calcsize('hhl')1538154```155156Распакованные поля можно именовать, присваивая их переменным или оборачивая результат в именованный кортеж:157158```python159>>> record = 'raymond   \x32\x12\x08\x01\x08'160>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)161162>>> from collections import namedtuple163>>> Student = namedtuple('Student', 'name serialnum school gradelevel')164>>> Student._make(unpack('<10sHHb', record))165Student(name='raymond   ', serialnum=4658, school=264, gradelevel=8)166```167168Порядок символов формата может влиять на размер, поскольку заполнение, необходимое для удовлетворения требований выравнивания, отличается:169170```python171>>> pack('ci', '*', 0x12131415)172'*\x00\x00\x00\x12\x13\x14\x15'173>>> pack('ic', 0x12131415, '*')174'\x12\x13\x14\x15*'175>>> calcsize('ci')1768177>>> calcsize('ic')1785179```180181Следующий формат `'llh0l'` указывает два байта заполнения в конце, предполагая, что значения типа long выровнены по границе в 4 байта:182183```python184>>> pack('llh0l', 1, 2, 3)185'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'186```187188Это работает только при использовании собственного размера и выравнивания; стандартный размер и выравнивание не обеспечивают никакого выравнивания.189190> **См. также**191>192> **Модуль [`array`](https://python-all.ru/2.7/library/array.html#module-array)**193>194> Упакованное бинарное хранение однородных данных.195>196> **Модуль [`xdrlib`](https://python-all.ru/2.7/library/xdrlib.html#module-xdrlib)**197>198> Упаковка и распаковка данных XDR.199200## 7.3.3. Классы201202Модуль [`struct`](https://python-all.ru/2.7/library/struct.html#module-struct) также определяет следующий тип:203204#### `class struct.Struct(format)`205206Возвращает новый объект Struct, который записывает и читает двоичные данные в соответствии со строкой формата *format*. Создание объекта Struct один раз и вызов его методов эффективнее, чем вызов функций [`struct`](https://python-all.ru/2.7/library/struct.html#module-struct) с тем же форматом, поскольку строку формата нужно скомпилировать только один раз.207208Новое в версии 2.5.209210Скомпилированные объекты Struct поддерживают следующие методы и атрибуты:211212#### `pack(v1, v2, ...)`213214Идентично функции [`pack()`](https://python-all.ru/2.7/library/struct.html#struct.pack), использует скомпилированный формат. (`len(result)` будет равно `self.size`.)215216#### `pack_into(buffer, offset, v1, v2, ...)`217218Идентично функции [`pack_into()`](https://python-all.ru/2.7/library/struct.html#struct.pack_into), использует скомпилированный формат.219220#### `unpack(string)`221222Идентично функции [`unpack()`](https://python-all.ru/2.7/library/struct.html#struct.unpack), с использованием скомпилированного формата. (`len(string)` должно равняться `self.size`).223224#### `unpack_from(buffer, offset=0)`225226Идентично функции [`unpack_from()`](https://python-all.ru/2.7/library/struct.html#struct.unpack_from), с использованием скомпилированного формата. (`len(buffer[offset:])` должно быть не менее `self.size`).227228#### `format`229230Строка форматирования, используемая для создания этого объекта Struct.231232#### `size`233234Вычисленный размер структуры (и, следовательно, строки), соответствующий [`format`](https://python-all.ru/2.7/library/functions.html#format).235