Модуль struct. Упаковка/распаковка данных. Базовые методы модуля
Содержание
- 1. Использование модуля struct. Упакованные двоичные данные
- 2. Базовые методы модуля struct
- 3. Форматированные строки
- Связанные темы
Поиск на других ресурсах:
1. Использование модуля struct. Упакованные двоичные данные
Модуль struct в Python используется для создания и вытягивания упакованных двоичных данных из строк. В модуле struct байты данных интерпретируются как упакованные двоичные данные, которые могут быть представлены объектами типов bytes или bytearray.
В модуле помещаются средства преобразования между значениями Python и структурами C, которые представлены в виде байтовых объектов Python. Такие преобразования используются при обработке двоичных данных, которые сохраняются в файлах или получаются из сетевых подключений, и т.п.
Для обеспечения компактного описания C-структур и преобразования в значения (из значений) Python используются строки формата.
⇑
2. Базовые методы модуля struct
В модуле struct помещаются несколько базовых методов, которые можно использовать для упаковки и распаковки данных.
2.1. Методы pack() и unpack(). Упаковка и распаковка данных
Для упаковки и распаковки данных используются методы pack(), unpack(). Процесс упаковки/распаковывки реализуется в соответствии со строкой формата.
В соответствии с документацией, общая форма использования метода pack() следующая
obj = struct.pack(format, v1, v2, ...)
где
- format – строка формата. Эта строка формируется в соответствии с правилами, которые заложены в таблицах (смотрите пункт 3);
- v1, v2, … – значения (объекты), которые нужно упаковать;
- obj – упакованный двоичный объект.
Функция unpack() выполняет обратные по отношению к pack() операции. Она позволяет получить исходный объект на основе упакованного объекта. Общая форма использования функции следующая:
obj = struct.unpack(format, buffer)
здесь
- buffer – буфер, в котором записан объект, который был предварительно упакован функцией pack(). Размер этого объекта должен совпадать с размером, заданным в строке формата format;
- format – строка формата на основе которой получается распакованный двоичный объект obj;
- obj – результирующий объект, которым может быть список, кортеж, множество, словарь и т.п.
При вызове функции unpack() строка формата должна совпадать с такой же строкой, которая была задана функцией pack().
Пример. С целью демонстрации осуществляется упаковка/распаковка списка чисел.
# Модуль struct. Методы pack(), unpack() # Упаковать/распаковать список чисел # 1. Заданный список чисел LS = [ 1, 3, 9, 12 ] # 2. Подключить модуль struct import struct # 3. Упаковать список чисел. Метод pack() pack_obj = struct.pack('>4і', LS[0], LS[1], LS[2], LS[3]) # 4. Вывести упакованный объект pack_obj print('pack_obj = ', pack_obj) # 5. Распаковать список чисел. Метод unpack(). # Результатом есть кортеж T2 T2 = struct.unpack('>4і', pack_obj) # T2 = (1, 3, 9, 12) # 6. Вывести распакованный объект T2 print('T2 = ', T2) # 7. Конвертировать кортеж T2 в список LS2 LS2 = list(T2) # LS2 = [1, 3, 9, 12] # 8. Вывести список LS2 print('LS2 = ', LS2)
Результат работы программы
pack_obj = b'\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\t\x00\x00\x00\x0c' T2 = (1, 3, 9, 12) LS2 = [1, 3, 9, 12]
⇑
2.2. Метод calcsize(). Размер упакованного объекта
Метод calcsize() возвращает размер объекта, созданного методом pack().
Пример.
# Модуль struct. # Метод calcsize(). Определить размер упакованного объекта # 1. Подключить модуль struct import struct # 2. Определить размер упакованного списка чисел # 2.1. Заданный список вещественных чисел LS = [ 2.88, 3.9, -10.5 ] # 2.2. Упаковать список LS. Метод pack() pack_obj = struct.pack('>3f', LS[0], LS[1], LS[2]) # 2.3. Вывести упакованный объект pack_obj print('pack_obj = ', pack_obj) # 2.4. Вывести размер объекта pack_obj size = struct.calcsize('>3f') # size = 12 print('size = ', size) # 3. Определить размер упакованного кортежа строк # 3.1. Заданный кортеж из двух строк TS = ( 'Hello', 'abcd') # 3.2. Упаковать кортеж TS pack_obj = struct.pack('<5s4s', TS[0].encode(), TS[1].encode()) # 3.3. Вывести упакованный объект print('pack_obj = ', pack_obj) # 3.4. Вывести размер упакованного кортежа size = struct.calcsize('<5s4s') # size = 9 print('size = ', size)
Результат выполнения программы
pack_obj = b'@8Q\xec@y\x99\x9a\xc1(\x00\x00' size = 12 pack_obj = b'Helloabcd' size = 9
⇑
3. Форматированные строки
3.1. Установка порядка байт, размера и выравнивания на основании символа формата
В языке Python способ упаковки строки определяется на основе первого символа строки формата. Этот символ определяет:
- порядок байт, который формируется с помощью символов @, =, <, >, !. Если не указать этого параметра, то принимается символ @;
- размер в байтах упакованных данных. В этом случае первыми используются цифры, которые обозначают число;
- выравнивание, устанавливаемое системой.
В соответствии с документацией Python в строке формата порядок байт, размер и выравнивание формируются согласно первому символу формата. Возможные первые символы формата отображены в следующей таблице.
Символ | Порядок байт | Размер | Выравнивание |
@ | Естественный (зависит от хост-системы) | Естественный | Естественное |
= | Естественной | Стандартный | Отсутствует |
< | little-endian | Стандартный | Отсутствует |
> | big-endian | Стандартный | Отсутствует |
! | сетевой (аналог big-endian) | Стандартный | Отсутствует |
Значение порядка байт может быть одним из 4-х:
- естественной порядок (native). Этот порядок может быть или little-endian или big-endian. Данный порядок определяется в зависимости от хост-системы;
- порядок типа little-endian. При таком порядке первым обрабатывается младший байт, а затем уже старший байт;
- порядок типа big-endian. В этом случае первым обрабатывается старший байт, а затем уже младший байт;
- сетевой порядок (network), который по умолчанию равен порядку big-endian.
Размер упакованных данных может быть одним из двух:
- естественный – определяется с помощью инструкции sizeof компилятора языка C;
- стандартный – определяется на основе символа формата в соответствии с нижеследующей таблицей.
Таблица. Определение стандартного размера упакованных данных в зависимости от символа формата
Формат | Тип в языке C | Тип в языке Python | Стандартный размер |
x | pad byte | без значения | |
c | char | байты длиной 1 | 1 |
b | signed char | integer | 1 |
B | unsigned char | integer | 1 |
? | _Bool | bool | 1 |
h | short | integer | 2 |
H | unsigned short | integer | 2 |
i | int | integer | 4 |
I | unsigned int | integer | 4 |
l | long | integer | 4 |
L | unsigned long | integer | 4 |
q | long long | integer | 8 |
Q | unsigned long long | integer | 8 |
n | ssize_t | integer | |
N | size_t | integer | |
e | float (экспоненциальный формат) | float | 2 |
f | float | float | 4 |
d | double | float | 8 |
s | char[] | bytes | |
p | char[] | bytes | |
P | void* | integer |
⇑
3.2. Примеры форматированных строк для разных типов данных
ii - два числа типа int 2i - два числа типа int 10f - 10 чисел типа float >i8s - порядок байт big-endian, число типа int, строка из 8 символов 8dif - 8 чисел типа double, 1 число типа int, 1 число типа float =bi - естественной порядок, значение типа bool, число типа int
⇑
Связанные темы
⇑