struct

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

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

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

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

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

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

  • struct.error exception

  • struct.pack () - возвращает байтовый объект с упакованными в заданном формате данными

  • struct.pack_into ()

  • struct.unpack () - распаковывает упакованный байтовый объект и возвращает кортеж

  • struct.unpack_from ()

  • struct.iter_unpack ()

  • struct.calcsize ()

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

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

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

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

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

Символ

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

Размер

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

@

собственный

собственный

собственный

=

собственный

стандартный

нет

<

обратный (little-endian)

стандартный

нет

>

прямой (big-endian)

стандартный

нет

!

сетевой (равен прямому)

стандартный

нет

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

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

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

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

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

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

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

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

  2. При использовании нестандартного размера и выравнивания отступы не добавляются, например с помощью '<', '>', '=' и '!'.

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

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

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

Формат

Тип С

Тип Python

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

Примечание

x

pad byte

нет значения

c

char

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

1

b

signed char

integer

1

(1), (2)

B

unsigned byte

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

size_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' доступен только для собственного порядка байтов (выбран по умолчанию или с помощью символа порядка байтов '@'). Символ порядка байтов '=' выбирает использование прямого или обратного порядка байтов в зависимости от хост-системы. Модуль struct не интерпретирует это как собственный порядок, поэтому формат 'P' недоступен.

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

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

Примеры

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

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

Смотрите также:

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

  • модуль xdrlib - упаковка и распаковка данных XDR

Классы

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

  • struct.Struct class

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

  • pack ()

  • pack_into ()

  • unpack ()

  • unpack_from ()

  • iter_unpack ()

  • format

  • size

Last updated