struct — Интерпретация байтов как упакованные двоичные данные

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


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

Примечание

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

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

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

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

exception struct.error

Исключения, выдвигавшиеся в различных случаях; аргумент - это строка, описывающий то, что неправильно.

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

Возвращает байтовый объект, содержащий значения 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)

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

Последовательности формата

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

Порядок байтов, размер и выравнивание

По умолчанию типы C представлены в собственном формате и в порядке байтов компьютера и правильно выровнены путем пропуска байтов панели (в соответствии с правилами, используемый компилятором C).

Альтернативно, первый символ строка формата может быть используемый для указания порядка байтов, размера и выравнивания упакованных данных в соответствии со следующей таблицей

Символ Порядок байтов Размер Выравнивание
@ родной родной родной
= родной стандарт никакого
< прямой порядок байтов стандарт никакого
> обратный порядок байт стандарт никакого
! сеть (= обратный порядок байт) стандарт никакого

Если первый символ не является одним из этих, предполагается '@'.

Собственный порядок байтов - обратный порядок байт (big-endian) или прямой порядок байтов (little-endian), в зависимости от системы хоста. Например, Intel x86 и AMD64 (x86-64) с прямым порядком байтов; Motorola 68000 и PowerPC G5 с обратным порядком байт; характеристики ARM и Intel Itanium могут переключаться (bi-endian). Используйте sys.byteorder для получения порядока байт системы.

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

Стандартный размер зависит только от символ формата; см. таблицу в разделе Форматные символы.

Обратите внимание на разницу между '@' и '=': оба используют собственный порядок байтов, но размер и выравнивание последнего стандартизированы.

Форма '!' представляет сетевой порядок байтов, который всегда является прямым порядком байтов, как определено в IETF RFC 1700.

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

Примечания:

  1. Заполнение добавляется только автоматически между последовательными элементами структуры. Заполнение не добавляется в начале или в конце структуры кодированный.
  2. Заполнение не добавляется при использовании неродного размера и выравнивания, например, с „<“, „>“, „=“ и „!“.
  3. Чтобы выровнять конец структуры по требованию выравнивания определенного типа, завершите формат код для этого типа с числом повторений, равным нулю. См. Примеры.

Форматные символы

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

Формат C Тип Python тип Стандартный размер Примечания
x байт набивки нет значения    
c char байты длины 1 1  
b signed char integer 1 (1), (2)
B unsigned char integer 1 (2)
? _Bool bool 1 (1)
h short integer 2 (2)
H unsigned short integer 2 (2)
i int integer 4 (2)
I unsigned int integer 4 (2)
l long integer 4 (2)
L unsigned long integer 4 (2)
q long long integer 8 (2)
Q unsigned long long integer 8 (2)
n ssize_t integer   (3)
N size_t integer   (3)
e (6) float 2 (4)
f float float 4 (4)
d double float 8 (4)
s char[] bytes    
p char[] bytes    
P void * integer   (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: на типовой машине неподписанная короткометражка может быть используемый для хранения, но не для математических операций. Дополнительные сведения см. на странице википедии в формат с плавающей точкой половинной точности.

Формату символ может предшествовать интегральный счетчик повторов. Например, формат строка '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' символ кодирует «Pascal строку», означающий короткую строку переменной длины, хранящийся в фиксированное количество байтов, задаваемый счетчиком. Первый сохраненный байт - это длина строки, или 255, в зависимости от того, что меньше. Далее следуют байты строки. Если строка, переданное pack(), слишком длинное (длинное, чем число минус 1), сохраняются только первые count-1 байт строка. Если строка короче count-1, он заполняется нулевыми байтами, так что все байты в точности подсчитываются используемый. Обратите внимание, что для unpack(), формат символ 'p' потребляет байты count, но что строка возвращенный никогда не может содержать больше чем 255 байтов.

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

Примеры

Примечание

Все примеры предполагают собственный порядок байтов, размер и выравнивание с биг-эндиевой машиной.

Основной пример упаковки/распаковки трех целых чисел:

>>> 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' задает два байта в конце, предполагая, что длины выровнены по 4-байтовым границам:

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

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

См.также

Модуль array упакованное двоичное хранилище однородных данных.

Модуль xdrlib упаковка и распаковка данных XDR.

Классы

Модуль 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

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