Spec-Zone.ru › Python 3.7

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

Возвращает объект 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.

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

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

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

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

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

Символ

Порядок байтов

Размер

Выравнивание

@

родной

родной

родной

=

родной

стандартный

нет

<

маленький порядок байтов

стандартный

нет

>

большой порядок байтов

стандартный

нет

!

сетевой (= большой порядок байтов)

стандартный

нет

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

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

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

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

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

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

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

Примечания:

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

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

Символы формата имеют следующее значение; преобразование между 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)

вещественное число

2

(4)

f

float

вещественное число

4

(4)

d

double

вещественное число

8

(4)

s

char[]

байты

p

char[]

байты

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-endian или big-endian в зависимости от системы. Модуль struct не интерпретирует это как родной порядок, поэтому формат 'P' недоступен.
  6. Тип IEEE 754 binary16 «половинной точности» был введён в 2008 году в пересмотренном стандарте IEEE 754. Он имеет бит знака, 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, она дополняется нулевыми байтами, чтобы использовалось ровно count байтов. Обратите внимание, что для unpack(), символ формата 'p' потребляет count байтов, но возвращаемая строка никогда не может содержать более 255 байтов.

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

Примеры

Примечание

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

Классы

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

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

Spec-Zone.ru

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