Содержание страницы
7.3. struct – Интерпретация строк как упакованных двоичных данных¶struct – Interpret strings as packed binary data
Этот модуль выполняет преобразование между значениями Python и структурами C, представленными в виде строк Python. Его можно использовать для обработки двоичных данных, хранящихся в файлах, полученных из сетевых соединений и других источников. Для компактного описания структуры C-структур и предполагаемого преобразования в/из значений Python в нём используются строки формата.
Примечание
По умолчанию результат упаковки заданной C-структуры включает байты заполнения для сохранения правильного выравнивания для задействованных C-типов; аналогично, выравнивание учитывается при распаковке. Такое поведение выбрано, чтобы байты упакованной структуры точно соответствовали расположению в памяти соответствующей C-структуры. Для обработки платформенно-независимых форматов данных или пропуска неявных байтов заполнения используйте standard размер и выравнивание вместо native размера и выравнивания: см. Порядок байтов, размер и выравнивание для подробностей.
7.3.1. Функции и исключения¶Functions and Exceptions
Модуль определяет следующие исключения и функции:
-
exception
struct.error¶ Исключение, вызываемое в различных ситуациях; аргумент – строка, описывающая, что не так.
-
struct.pack(fmt, v1, v2, ...)¶ Возвращает строку, содержащую значения
v1, v2, ..., упакованные согласно заданному формату. Аргументы должны точно соответствовать значениям, требуемым форматом.
-
struct.pack_into(fmt, buffer, offset, v1, v2, ...)¶ Упаковывает значения
v1, v2, ...согласно заданному формату и записывает упакованные байты в записываемый буфер, начиная с смещения. Обратите внимание, что смещение является обязательным аргументом.Новое в версии 2.5.
-
struct.unpack(fmt, string)¶ Распаковывает строку (предположительно упакованную с помощью
pack(fmt, ...)) в соответствии с заданным форматом. Результатом является кортеж, даже если он содержит ровно один элемент. Строка должна содержать ровно столько данных, сколько требует формат (len(string)должно равнятьсяcalcsize(fmt)).
-
struct.unpack_from(fmt, buffer[, offset=0])¶ Распаковывает буфер в соответствии с заданным форматом. Результатом является кортеж, даже если он содержит ровно один элемент. Буфер должен содержать как минимум столько данных, сколько требует формат (
len(buffer[offset:])должно быть не менееcalcsize(fmt)).Новое в версии 2.5.
-
struct.calcsize(fmt)¶ Возвращает размер структуры (и, следовательно, строки), соответствующий заданному формату.
7.3.2. Строки формата¶Format Strings
Строки формата – это механизм, используемый для указания ожидаемого расположения данных при упаковке и распаковке. Они составляются из символов формата, которые задают тип упаковываемых/распаковываемых данных. Кроме того, существуют специальные символы для управления порядком байтов, размером и выравниванием.
7.3.2.1. Порядок байтов, размер и выравнивание¶Byte Order, Size, and Alignment
По умолчанию типы C представляются в собственном формате и порядке байтов машины и правильно выравниваются путём пропуска байтов заполнения при необходимости (в соответствии с правилами, используемыми компилятором C).
В качестве альтернативы, первый символ строки формата может использоваться для указания порядка байтов, размера и выравнивания упакованных данных, как показано в следующей таблице:
Символ |
Порядок байтов |
Размер |
Выравнивание |
|---|---|---|---|
|
собственный |
собственный |
собственный |
|
собственный |
стандартный |
нет |
|
little-endian |
стандартный |
нет |
|
big-endian |
стандартный |
нет |
|
сетевой порядок байт (= big-endian) |
стандартный |
нет |
Если первый символ не один из этих, предполагается '@'.
Собственный порядок байтов может быть big-endian или little-endian в зависимости от хост-системы. Например, Intel x86 и AMD64 (x86-64) используют little-endian; Motorola 68000 и PowerPC G5 – big-endian; ARM и Intel Itanium поддерживают переключаемый порядок байтов (bi-endian). Используйте sys.byteorder для проверки порядка байтов вашей системы.
Собственный размер и выравнивание определяются с помощью выражения sizeof компилятора C. Это всегда используется вместе с собственным порядком байт.
Стандартный размер зависит только от символа формата; см. таблицу в разделе Символы формата.
Обратите внимание на различие между '@' и '=': оба используют собственный порядок байт, но размер и выравнивание второго стандартизированы.
Форма '!' доступна для тех несчастных, кто утверждает, что не может запомнить, является ли сетевой порядок байтов big-endian или little-endian.
Нет способа указать несобственный порядок байт (принудительную перестановку байт); используйте соответствующий выбор из '<' или '>'.
Примечания:
Заполнение автоматически добавляется только между последовательными членами структуры. Начало и конец закодированной структуры не дополняются.
Заполнение не добавляется при использовании несобственного размера и выравнивания, например, с ‘<’, ‘>’, ‘=’ и ‘!’.
Чтобы выровнять конец структуры по требованию выравнивания конкретного типа, завершите формат кодом этого типа с нулевым количеством повторений. См. Примеры.
7.3.2.2. Символы формата¶Format Characters
Символы формата имеют следующее значение; преобразование между значениями C и Python должно быть очевидным, исходя из их типов. Столбец «Стандартный размер» указывает размер упакованного значения в байтах при использовании стандартного размера; то есть когда строка формата начинается с одного из '<', '>', '!' или '='. При использовании собственного размера размер упакованного значения зависит от платформы.
Формат |
Тип C |
Тип Python |
Стандартный размер |
Примечания |
|---|---|---|---|---|
|
байт заполнения |
нет значения |
||
|
|
строка длиной 1 |
1 |
|
|
|
целое число |
1 |
(3) |
|
|
целое число |
1 |
(3) |
|
|
bool |
1 |
(1) |
|
|
целое число |
2 |
(3) |
|
|
целое число |
2 |
(3) |
|
|
целое число |
4 |
(3) |
|
|
целое число |
4 |
(3) |
|
|
целое число |
4 |
(3) |
|
|
целое число |
4 |
(3) |
|
|
целое число |
8 |
(2), (3) |
|
|
целое число |
8 |
(2), (3) |
|
|
float |
4 |
(4) |
|
|
float |
8 |
(4) |
|
|
строка |
||
|
|
строка |
||
|
|
целое число |
(5), (3) |
Примечания:
Код преобразования
'?'соответствует типу_Bool, определённому в стандарте C99. Если этот тип недоступен, он эмулируется с помощьюchar. В стандартном режиме он всегда представлен одним байтом.Новое в версии 2.6.
Коды преобразования
'q'и'Q'доступны в родном режиме только в том случае, если компилятор C платформы поддерживает Clong longили, в Windows,__int64. Они всегда доступны в стандартных режимах.Новое в версии 2.2.
При попытке упаковать нецелое число с помощью любого из кодов преобразования целых чисел, если нецелое число имеет метод
__index__(), то этот метод вызывается для преобразования аргумента в целое число перед упаковкой. Если метод__index__()не существует или вызов__index__()вызываетTypeError, то используется метод__int__(). Однако использование__int__()устарело и будет вызыватьDeprecationWarning.Изменено в версии 2.7: Использование метода
__index__()для нецелых чисел является новым в версии 2.7.Изменено в версии 2.7: До версии 2.7 не все коды преобразования целых чисел использовали метод
__int__()для преобразования, иDeprecationWarningвызывалось только для аргументов типа float.Для кодов преобразования
'f'и'd'упакованное представление использует формат IEEE 754 binary32 (для'f') или binary64 (для'd'), независимо от формата чисел с плавающей запятой, используемого платформой.Символ формата
'P'доступен только для родного порядка байтов (выбранного по умолчанию или с символом порядка байтов'@'). Символ порядка байтов'='выбирает порядок little- или big-endian в зависимости от хост-системы. Модуль struct не интерпретирует это как родной порядок, поэтому формат'P'недоступен.
Символу формата может предшествовать целочисленный счётчик повторений. Например,
строка формата '4h' означает то же самое, что и 'hhhh'.
Пробельные символы между форматами игнорируются; однако счётчик и его формат не должны содержать пробелов.
Для символа формата 's' количество интерпретируется как размер строки, а не как число повторений, как для других символов формата; например, '10s' означает одну 10-байтовую строку, тогда как '10c' означает 10 символов. Если количество не указано, по умолчанию оно равно 1. При упаковке строка усекается или дополняется нулевыми байтами по мере необходимости, чтобы она поместилась. При распаковке результирующая строка всегда содержит ровно указанное количество байтов. В особом случае '0s' означает одну пустую строку (тогда как '0c' означает 0 символов).
Символ формата 'p' кодирует «строку Pascal», то есть короткую строку переменной длины, хранящуюся в фиксированном числе байтов, заданном количеством. Первым сохраняемым байтом является длина строки или 255, в зависимости от того, что меньше. Затем следуют байты строки. Если строка, переданная в pack(), слишком длинная (длиннее, чем count минус 1), сохраняются только первые count-1 байтов строки. Если строка короче count-1, она дополняется нулевыми байтами так, чтобы в итоге было использовано ровно count байтов. Обратите внимание, что для unpack() символ формата 'p' потребляет count байтов, но возвращаемая строка никогда не может содержать более 255 символов.
Для символа формата 'P' возвращаемым значением является целое число Python (int) или длинное целое (long) в зависимости от размера, необходимого для хранения указателя после приведения к целочисленному типу. Нулевой указатель (NULL) всегда возвращается как целое число Python 0. При упаковке значений размером с указатель можно использовать объекты int или long. Например, процессоры Alpha и Merced используют 64-битные указатели, поэтому для хранения указателя будет использоваться длинное целое Python; на других платформах используются 32-битные указатели, и будет использоваться целое Python.
Для символа формата '?' возвращаемое значение – True или
False. При упаковке используется истинностное значение объекта-аргумента.
Будет упакован либо 0, либо 1 в родном или стандартном представлении bool, и
любое ненулевое значение будет True при распаковке.
7.3.2.3. Примеры¶Examples
Примечание
Все примеры предполагают собственный порядок байтов, размер и выравнивание на машине с big-endian.
Простой пример упаковки/распаковки трёх целых чисел:
>>> 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'
Это работает только при использовании собственного размера и выравнивания; стандартный размер и выравнивание не обеспечивают никакого выравнивания.
7.3.3. Классы¶Classes
Модуль struct также определяет следующий тип:
-
class
struct.Struct(format)¶ Возвращает новый объект Struct, который записывает и читает двоичные данные в соответствии со строкой формата format. Создание объекта Struct один раз и вызов его методов эффективнее, чем вызов функций
structс тем же форматом, поскольку строку формата нужно скомпилировать только один раз.Новое в версии 2.5.
Скомпилированные объекты Struct поддерживают следующие методы и атрибуты:
-
pack(v1, v2, ...)¶ Идентично функции
pack(), использует скомпилированный формат. (len(result)будет равноself.size.)
-
pack_into(buffer, offset, v1, v2, ...)¶ Идентично функции
pack_into(), использует скомпилированный формат.
-
unpack(string)¶ Идентично функции
unpack(), с использованием скомпилированного формата. (len(string)должно равнятьсяself.size).
-
unpack_from(buffer, offset=0)¶ Идентично функции
unpack_from(), с использованием скомпилированного формата. (len(buffer[offset:])должно быть не менееself.size).
-
format¶ Строка форматирования, используемая для создания этого объекта Struct.
-