Содержание страницы
struct – Интерпретация байтов как упакованных двоичных данных¶struct – Interpret bytes as packed binary data
Этот модуль выполняет преобразования между значениями Python и C-структурами, представленными в виде объектов bytes. В нём используются строки формата (описаны ниже) как компактные описания расположения C-структур и предполагаемого преобразования в/из значений Python. Это может использоваться для обработки двоичных данных, хранящихся в файлах или полученных из сетевых соединений, среди прочих источников.
Модуль определяет следующие исключения и функции:
- exception struct.error¶
- Исключение, возникающее в различных ситуациях; аргумент – строка, описывающая, что не так.
- struct.pack(fmt, v1, v2, ...)¶
- Возвращает объект bytes, содержащий значения v1, v2, ..., упакованные в соответствии с заданным форматом. Аргументы должны точно соответствовать значениям, требуемым форматом.
- struct.pack_into(fmt, buffer, offset, v1, v2, ...)¶
- Упаковывает значения v1, v2, ... в соответствии с заданным форматом и записывает упакованные байты в записываемый buffer, начиная с offset. Обратите внимание, что смещение является обязательным аргументом.
- struct.unpack(fmt, bytes)¶
- Распаковывает байты (предположительно упакованные с помощью pack(fmt, ...)) в соответствии с заданным форматом. Результатом является кортеж, даже если он содержит ровно один элемент. Байты должны содержать ровно столько данных, сколько требуется форматом (len(bytes) должно равняться calcsize(fmt)).
- struct.unpack_from(fmt, buffer[, offset=0])¶
- Распаковывает buffer в соответствии с заданным форматом. Результатом является кортеж, даже если он содержит ровно один элемент. buffer должен содержать как минимум столько данных, сколько требуется форматом (len(buffer[offset:]) должно быть не меньше calcsize(fmt)).
- 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 * | целое число |
Примечания:
- Коды преобразования c, s и p работают с объектами bytes, но упаковка с этими кодами также поддерживает объекты str, которые кодируются с использованием UTF-8.
- Код преобразования '?' соответствует типу _Bool, определённому в C99. Если этот тип недоступен, он имитируется с помощью char. В стандартном режиме он всегда представлен одним байтом.
- Коды преобразования 'q' и 'Q' доступны в родном режиме, только если компилятор C платформы поддерживает C long long или, в Windows, __int64. Они всегда доступны в стандартных режимах.
Символу формата может предшествовать целочисленный счетчик повторений. Например, строка формата '4h' означает то же самое, что и 'hhhh'.
Пробельные символы между форматами игнорируются; однако счётчик и его формат не должны содержать пробелов.
Для символа формата 's' количество интерпретируется как длина строки в байтах, а не как количество повторений, как для других символов формата; например, '10s' означает одну строку длиной 10 байт, тогда как '10c' означает 10 символов. При упаковке строка усекается или дополняется нулевыми байтами по мере необходимости, чтобы соответствовать заданной длине. При распаковке результирующий объект bytes всегда содержит ровно указанное количество байт. В частном случае '0s' означает одну пустую строку (а '0c' означает 0 символов).
Символ формата 'p' кодирует «строку Паскаля», то есть короткую строку переменной длины, хранящуюся в фиксированном количестве байтов. Значение count – это общее количество сохраняемых байтов. Первый сохраняемый байт – это длина строки или 255, в зависимости от того, что меньше. Затем следуют байты строки. Если строка, переданная в pack(), слишком длинная (длиннее, чем count минус 1), сохраняются только первые count-1 байтов строки. Если строка короче count-1, она дополняется нулевыми байтами, чтобы в итоге было использовано ровно count байтов. Обратите внимание, что для unpack() символ формата 'p' потребляет count байтов, но возвращаемая строка никогда не может содержать более 255 байтов.
Для символа формата '?' возвращаемым значением является либо True, либо 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 машине):
>>> 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-байтовым границам). Это работает только в режиме родных размеров и выравнивания; в стандартном режиме выравнивание не навязывается.
Распакованные поля можно именовать, присваивая их переменным или оборачивая результат в именованный кортеж:
>>> 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)
См. также
Объекты Struct¶Struct Objects
Модуль struct также определяет следующий тип:
- class struct.Struct(format)¶
Возвращает новый объект Struct, который записывает и читает двоичные данные в соответствии со строкой формата format. Создание объекта Struct один раз и вызов его методов эффективнее, чем вызов функций struct с тем же форматом, поскольку строку формата нужно скомпилировать только один раз.
Скомпилированные объекты Struct поддерживают следующие методы и атрибуты:
- pack(v1, v2, ...)¶
- Идентично функции pack() с использованием скомпилированного формата. (len(result) будет равно self.size.)
- pack_into(buffer, offset, v1, v2, ...)¶
- Идентично функции pack_into() с использованием скомпилированного формата.
- unpack(bytes)¶
- Идентична функции unpack(), использующей скомпилированный формат. (len(bytes) должно быть равно self.size).
- unpack_from(buffer[, offset=0])¶
- Идентично функции unpack_from() с использованием скомпилированного формата. (len(buffer[offset:]) должно быть не менее self.size).
- format¶
- Строка форматирования, используемая для создания этого объекта Struct.