Spec-Zone.ru › Python 3.5

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

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

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

Примечание

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

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

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

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

exception struct.error

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

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

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

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

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

struct.unpack(fmt, buffer)

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

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

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

struct.iter_unpack(fmt, buffer)

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

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

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

struct.calcsize(fmt)

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

2. Строки формата

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

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

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

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

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

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

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

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

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

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

Форма '!' доступна для тех бедняг, которые утверждают, что не могут вспомнить, сетевой порядок байтов — большой или малый порядок байтов.

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

Примечания:

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

2.2. Символы формата

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

Формат Тип C Тип Python Стандартный размер Примечания
x байт заполнения нет значения
c char байты длиной 1 1
b signed char целое число 1 (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)
n ssize_t целое число (4)
N size_t целое число (4)
f float вещественное число 4 (5)
d double вещественное число 8 (5)
s char[] байты
p char[] байты
P void * целое число (6)

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

Примечания:

  1. Код преобразования '?' соответствует типу _Bool, определенному в C99. Если этот тип недоступен, он моделируется с помощью char. В стандартном режиме он всегда представлен одним байтом.
  2. Коды преобразования 'q' и 'Q' доступны только в родном режиме, если платформенный компилятор C поддерживает C long long, или, в Windows, __int64. Они всегда доступны в стандартных режимах.
  3. При попытке упаковать нецелое число с помощью любого из кодов преобразования целых чисел, если у нецелого числа есть метод __index__(), то этот метод вызывается для преобразования аргумента в целое число перед упаковкой.

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

  4. Коды преобразования 'n' и 'N' доступны только для родного размера (выбранного по умолчанию или с помощью символа порядка байтов '@'). Для стандартного размера можно использовать любой другой формат целого числа, который подходит для вашего приложения.
  5. Для кодов преобразования 'f' и 'd', упакованное представление использует формат IEEE 754 binary32 (для 'f') или binary64 (для 'd') независимо от формата чисел с плавающей запятой, используемого платформой.
  6. Символ формата 'P' доступен только для родного порядка байтов (выбранного по умолчанию или с символом порядка байтов '@'). Символ порядка байтов '=' выбирает использование порядка little- или big-endian на основе системы хоста. Модуль struct не интерпретирует это как родной порядок, поэтому формат 'P' недоступен.

Символ формата может быть предваряем целочисленным повторяющимся значением. Например, строка формата '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.

2.3. Примеры

Примечание

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

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

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

См. также

Module array
Упакованное двоичное хранение однородных данных.
Module xdrlib
Упаковка и распаковка данных XDR.

3. Классы

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

class struct.Struct(format)

Возвращает новый объект Struct, который записывает и считывает двоичные данные в соответствии со строкой формата format. Создание объекта 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.

size

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

© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.5/library/struct.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API