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

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.

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

Примечания:

  1. Заполнение автоматически добавляется только между последовательными членами структуры. Начало и конец закодированной структуры не дополняются.

  2. Заполнение не добавляется при использовании несобственного размера и выравнивания, например, с ‘<’, ‘>’, ‘=’ и ‘!’.

  3. Чтобы выровнять конец структуры по требованию выравнивания конкретного типа, завершите формат кодом этого типа с нулевым количеством повторений. См. Примеры.

7.3.2.2. Символы форматаFormat Characters

Символы формата имеют следующее значение; преобразование между значениями C и Python должно быть очевидным, исходя из их типов. Столбец «Стандартный размер» указывает размер упакованного значения в байтах при использовании стандартного размера; то есть когда строка формата начинается с одного из '<', '>', '!' или '='. При использовании собственного размера размер упакованного значения зависит от платформы.

Формат

Тип C

Тип Python

Стандартный размер

Примечания

x

байт заполнения

нет значения

c

char

строка длиной 1

1

b

signed char

целое число

1

(3)

B

unsigned char

целое число

1

(3)

?

_Bool

bool

1

(1)

h

short

целое число

2

(3)

H

unsigned short

целое число

2

(3)

i

int

целое число

4

(3)

I

unsigned int

целое число

4

(3)

l

long

целое число

4

(3)

L

unsigned long

целое число

4

(3)

q

long long

целое число

8

(2), (3)

Q

unsigned long long

целое число

8

(2), (3)

f

float

float

4

(4)

d

double

float

8

(4)

s

char[]

строка

p

char[]

строка

P

void *

целое число

(5), (3)

Примечания:

  1. Код преобразования '?' соответствует типу _Bool, определённому в стандарте C99. Если этот тип недоступен, он эмулируется с помощью char. В стандартном режиме он всегда представлен одним байтом.

    Новое в версии 2.6.

  2. Коды преобразования 'q' и 'Q' доступны в родном режиме только в том случае, если компилятор C платформы поддерживает C long long или, в Windows, __int64. Они всегда доступны в стандартных режимах.

    Новое в версии 2.2.

  3. При попытке упаковать нецелое число с помощью любого из кодов преобразования целых чисел, если нецелое число имеет метод __index__(), то этот метод вызывается для преобразования аргумента в целое число перед упаковкой. Если метод __index__() не существует или вызов __index__() вызывает TypeError, то используется метод __int__(). Однако использование __int__() устарело и будет вызывать DeprecationWarning.

    Изменено в версии 2.7: Использование метода __index__() для нецелых чисел является новым в версии 2.7.

    Изменено в версии 2.7: До версии 2.7 не все коды преобразования целых чисел использовали метод __int__() для преобразования, и DeprecationWarning вызывалось только для аргументов типа float.

  4. Для кодов преобразования 'f' и 'd' упакованное представление использует формат IEEE 754 binary32 (для 'f') или binary64 (для 'd'), независимо от формата чисел с плавающей запятой, используемого платформой.

  5. Символ формата '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'

Это работает только при использовании собственного размера и выравнивания; стандартный размер и выравнивание не обеспечивают никакого выравнивания.

См. также

Модуль array

Упакованное бинарное хранение однородных данных.

Модуль xdrlib

Упаковка и распаковка данных XDR.

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.

size

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