struct
struct - интерпретация байтов как упакованных двоичных данных
Этот модуль выполняет преобразования между значениями Python и структурами C, представленными как байтовые объекты Python. Это может быть использовано при обработке двоичных данных, хранящихся в файлах или из сетевых подключений, среди других источников. Он использует строки формата как компактное описание макета структур C и предполагаемого преобразования в/из значений Python.
Некоторые функции 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 порядок байтов (принудительная замена байтов); используйте соответствующий выбор '<'
или '>'
.
Символы формата
Символы формата имеют следующее значение; преобразование между значениями 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'
.
Символу формата может предшествовать целое число повторов. Например, строка формата '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
при распаковке.
Примеры
Базовый пример упаковки/распаковки трех целых чисел:
>>> 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'
Это работает, только когда действуют собственный размер и выравнивание; стандартный размер и выравнивание не требует совмещения.
Классы
Модуль struct также определяет следующий тип:
struct.Struct class
Скомпилированные объекты Struct поддерживают следующие методы и атрибуты:
pack ()
pack_into ()
unpack ()
unpack_from ()
iter_unpack ()
format
size
Last updated
Was this helpful?