Spec-Zone.ru › Python 3.9

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 для проверки порядка байтов вашей системы.

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

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

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

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

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

Примечания:

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

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

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

Формат

Тип C

Тип Python

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

Примечания

x

байт заполнения

нет значения

c

char

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

1

b

signed char

целое число

1

(1), (2)

B

unsigned char

целое число

1

(2)

?

_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. Коды преобразования '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: на типичной машине можно использовать беззнаковый 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: Ранее некоторые форматы целых чисел обрабатывали значения вне диапазона и вместо 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

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

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

Spec-Zone.ru

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