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

struct – Интерпретация байтов как упакованных двоичных данныхstruct – Interpret bytes as packed binary data

Исходный код: Lib/struct.py


Этот модуль выполняет преобразования между значениями Python и C-структурами, представленными в виде объектов bytes Python. Он может использоваться для обработки двоичных данных, хранящихся в файлах или получаемых из сетевых соединений, а также из других источников. В нём используются строки формата как компактное описание расположения C-структур и предполагаемого преобразования в/из значений Python.

Примечание

По умолчанию результат упаковки заданной C-структуры включает байты заполнения для сохранения правильного выравнивания для задействованных C-типов; аналогично, выравнивание учитывается при распаковке. Такое поведение выбрано, чтобы байты упакованной структуры точно соответствовали расположению в памяти соответствующей C-структуры. Для обработки платформенно-независимых форматов данных или пропуска неявных байтов заполнения используйте standard размер и выравнивание вместо native размера и выравнивания: см. Порядок байтов, размер и выравнивание для подробностей.

Некоторые функции struct (и методы Struct) принимают аргумент buffer (буфер). Он ссылается на объекты, реализующие протокол буфера и предоставляющие буфер для чтения или чтения-записи. Наиболее распространённые типы, используемые для этой цели, – bytes и bytearray, но многие другие типы, которые можно рассматривать как массив байтов, реализуют протокол буфера, поэтому их можно читать/заполнять без дополнительного копирования из объекта bytes.

Функции и исключенияFunctions and Exceptions

Модуль определяет следующие исключения и функции:

exception struct.error

Исключение, вызываемое в различных ситуациях; аргумент – строка, описывающая, что не так.

struct.pack(format, v1, v2, ...)

Возвращает объект bytes, содержащий значения v1, v2, …, упакованные в соответствии со строкой формата format. Аргументы должны точно соответствовать значениям, требуемым форматом.

struct.pack_into(format, buffer, offset, v1, v2, ...)

Упаковывает значения v1, v2, … в соответствии со строкой формата format и записывает упакованные байты в буфер buffer, начиная с позиции offset. Обратите внимание, что offset – обязательный аргумент.

struct.unpack(format, buffer)

Распаковывает из буфера buffer (предположительно упакованного с помощью pack(format, ...)) в соответствии со строкой формата format. Результат – кортеж, даже если он содержит ровно один элемент. Размер буфера в байтах должен соответствовать размеру, требуемому форматом, отражённому calcsize().

struct.unpack_from(format, buffer, offset=0)

Распаковывает из buffer, начиная с позиции offset, в соответствии со строкой формата format. Результат – кортеж, даже если он содержит всего один элемент. Размер буфера в байтах минус offset должен быть не меньше размера, требуемого форматом, как отражено в calcsize().

struct.iter_unpack(format, buffer)

Итеративно распаковывает данные из буфера buffer в соответствии со строкой формата format. Эта функция возвращает итератор, который будет читать из буфера блоки одинакового размера, пока всё его содержимое не будет исчерпано. Размер буфера в байтах должен быть кратен размеру, требуемому форматом, как указано в calcsize().

Каждая итерация возвращает кортеж, как указано в строке формата.

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

struct.calcsize(format)

Возвращает размер структуры (и, следовательно, объекта bytes, полученного с помощью pack(format, ...)), соответствующий строке формата format.

Строки форматаFormat Strings

Строки формата – это механизм, используемый для указания ожидаемого расположения данных при упаковке и распаковке. Они составляются из символов формата, которые задают тип упаковываемых/распаковываемых данных. Кроме того, существуют специальные символы для управления порядком байтов, размером и выравниванием.

Порядок байтов, размер и выравнивание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. Чтобы выровнять конец структуры по требованию выравнивания конкретного типа, завершите формат кодом этого типа с нулевым количеством повторений. См. Примеры.

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

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

Формат

Тип C

Тип Python

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

Примечания

x

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

нет значения

c

char

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

1

b

signed char

целое число

1

(1), (2)

B

unsigned char

целое число

1

(2)

?

_Bool

bool

1

(1)

h

short

целое число

2

(2)

H

unsigned short

целое число

2

(2)

i

int

целое число

4

(2)

I

unsigned int

целое число

4

(2)

l

long

целое число

4

(2)

L

unsigned long

целое число

4

(2)

q

long long

целое число

8

(2)

Q

unsigned long long

целое число

8

(2)

n

ssize_t

целое число

(3)

N

size_t

целое число

(3)

e

(6)

float

2

(4)

f

float

float

4

(4)

d

double

float

8

(4)

s

char[]

bytes

p

char[]

bytes

P

void *

целое число

(5)

Изменено в версии 3.3: Добавлена поддержка форматов 'n' и 'N'.

Изменено в версии 3.6: Добавлена поддержка формата 'e'.

Примечания:

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

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

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

  3. Коды преобразования 'n' и 'N' доступны только для родного размера (выбранного по умолчанию или с символом порядка байтов '@'). Для стандартного размера можно использовать любой из других целочисленных форматов, который подходит для приложения.

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

  5. Символ формата 'P' доступен только для родного порядка байтов (выбранного по умолчанию или с символом порядка байтов '@'). Символ порядка байтов '=' выбирает порядок little- или big-endian в зависимости от хост-системы. Модуль struct не интерпретирует это как родной порядок, поэтому формат 'P' недоступен.

  6. Тип IEEE 754 binary16 «половинной точности» был введён в редакции стандарта IEEE 754 2008 года. Он имеет знаковый бит, 5-битную экспоненту и 11-битную точность (10 бит хранятся явно) и может представлять числа от примерно 6.1e-05 до 6.5e+04 с полной точностью. Этот тип не получил широкой поддержки в компиляторах C: на типичной машине unsigned short можно использовать для хранения, но не для математических операций. См. страницу Википедии о формате чисел с плавающей запятой половинной точности для получения дополнительной информации.

Символу формата может предшествовать целочисленный счётчик повторений. Например, строка формата '4h' означает то же самое, что и 'hhhh'.

Пробельные символы между форматами игнорируются; однако счётчик и его формат не должны содержать пробелов.

Для символа формата 's' счётчик интерпретируется как длина строки в байтах, а не как количество повторений, как для других символов формата; например, '10s' означает одну 10-байтовую строку, а '10c' – 10 символов. Если счётчик не указан, по умолчанию он равен 1. При упаковке строка усекается или дополняется нулевыми байтами по мере необходимости, чтобы соответствовать размеру. При распаковке результирующий объект bytes всегда имеет ровно указанное количество байт. В особом случае '0s' означает одну пустую строку (а '0c' – 0 символов).

При упаковке значения x с использованием одного из целочисленных форматов ('b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q'), если x выходит за допустимый диапазон для этого формата, то вызывается struct.error.

Изменено в версии 3.1: В версии 3.0 некоторые целочисленные форматы выполняли перенос значений за пределами диапазона и вызывали DeprecationWarning вместо struct.error.

Символ форматирования 'p' кодирует «строку Паскаля» – короткую строку переменной длины, хранящуюся в фиксированном количестве байт, задаваемом счётчиком. Первым байтом хранится длина строки или 255 (выбирается меньшее). Затем следуют байты строки. Если строка, переданная в pack(), слишком длинна (длиннее, чем счётчик минус 1), сохраняются только первые count-1 байт строки. Если строка короче count-1, она дополняется нулевыми байтами так, чтобы всего было использовано ровно счётчик байт. Обратите внимание, что для unpack() символ форматирования 'p' потребляет count байт, но возвращаемая строка никогда не может содержать более 255 байт.

Для символа формата '?' возвращаемое значение – True или False. При упаковке используется истинностное значение объекта-аргумента. Будет упакован либо 0, либо 1 в родном или стандартном представлении bool, и любое ненулевое значение будет True при распаковке.

ПримерыExamples

Примечание

Все примеры предполагают собственный порядок байтов, размер и выравнивание на машине с 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

Распакованные поля можно именовать, присваивая их переменным или оборачивая результат в именованный кортеж:

>>> 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)

Порядок символов формата может влиять на размер, поскольку заполнение, необходимое для удовлетворения требований выравнивания, отличается:

>>> pack('ci', b'*', 0x12131415)
b'*\x00\x00\x00\x12\x13\x14\x15'
>>> pack('ic', 0x12131415, b'*')
b'\x12\x13\x14\x15*'
>>> calcsize('ci')
8
>>> calcsize('ic')
5

Следующий формат 'llh0l' указывает два байта заполнения в конце, предполагая, что значения типа long выровнены по границе в 4 байта:

>>> pack('llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'

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

См. также

Модуль array

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

Модуль xdrlib

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

КлассыClasses

Модуль struct также определяет следующий тип:

class struct.Struct(format)

Возвращает новый объект Struct, который записывает и читает двоичные данные в соответствии со строкой формата format. Создание объекта Struct один раз и вызов его методов эффективнее, чем вызов функций struct с тем же форматом, поскольку строку формата нужно скомпилировать только один раз.

Примечание

Скомпилированные версии последних строк формата, переданных в Struct и функции уровня модуля, кэшируются, поэтому программам, использующим лишь несколько строк формата, не нужно беспокоиться о повторном использовании одного экземпляра Struct.

Скомпилированные объекты Struct поддерживают следующие методы и атрибуты:

pack(v1, v2, ...)

Идентично функции pack(), использует скомпилированный формат. (len(result) будет равно size.)

pack_into(buffer, offset, v1, v2, ...)

Идентично функции pack_into(), использует скомпилированный формат.

unpack(buffer)

Идентично функции unpack(), использует скомпилированный формат. Размер буфера в байтах должен быть равен size.

unpack_from(buffer, offset=0)

Идентична функции unpack_from(), но использует скомпилированный формат. Размер буфера в байтах минус offset должен быть не менее size.

iter_unpack(buffer)

Идентично функции iter_unpack(), использует скомпилированный формат. Размер буфера в байтах должен быть кратен size.

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

format

Строка форматирования, используемая для создания этого объекта Struct.

Изменено в версии 3.7: Тип строки форматирования теперь str вместо bytes.

size

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