- Python. Модуль struct. Упаковка/распаковка данных. Базовые методы модуля
- Модуль struct . Упаковка/распаковка данных. Базовые методы модуля
- Связанные темы
- Python struct pack, unpack
- Python Struct
- Python Struct Functions
- Python struct.pack()
- Python struct.unpack()
- Python struct calcsize()
- Python struct pack_into(), unpack_from()
Python. Модуль struct. Упаковка/распаковка данных. Базовые методы модуля
Модуль struct . Упаковка/распаковка данных. Базовые методы модуля
Поиск на других ресурсах:
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(', TS[0].encode(), TS[1].encode()) # 3.3. Вывести упакованный объект print('pack_obj = ', pack_obj) # 3.4. Вывести размер упакованного кортежа size = struct.calcsize(') # 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
Связанные темы
Python struct pack, unpack
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Python struct module is capable of performing the conversions between the Python values and C structs, which are represented as Python Strings.
Python Struct
- Python struct module can be used in handling binary data stored in files, database or from network connections etc.
- It uses format Strings as compact descriptions of the layout of the C structs and the intended conversion to/from Python values.
Python Struct Functions
There are five important functions in struct module — pack() , unpack() , calcsize() , pack_into() and unpack_from() . In all these functions, we have to provide the format of the data to be converted into binary. Some of the popular format characters are:
?: boolean h: short l: long i: int f: float q: long long int
You can get the complete list of format characters here. Let’s start looking into struct module functions one by one.
Python struct.pack()
This function packs a list of values into a String representation of the specified type. The arguments must match the values required by the format exactly. Let’s quickly look at struct pack() example:
import struct var = struct.pack('hhl', 5, 10, 15) print(var) var = struct.pack('iii', 10, 20, 30) print(var)
When we run this script, we get the following representation: Note that ‘b’ in the Output stands for binary.
Python struct.unpack()
This function unpacks the packed value into its original representation with the specified format. This function always returns a tuple, even if there is only one element. Let’s quickly look at struct unpack() function example:
import struct var = struct.pack('hhl', 5, 10, 15) print(var) print(struct.unpack('hhl', var))
When we run this script, we get back our original representation: Clearly, we must tell the Python interpreter the format we need to unpack the values into.
Python struct calcsize()
This function calculates and returns the size of the String representation of struct with a given format. Size is calculated in terms of bytes. Let’s quickly look at an example code snippet:
import struct var = struct.pack('hhl', 5, 10, 15) print(var) print("Size of String representation is <>.".format(struct.calcsize('hhl')))
When we run this script, we get the following representation:
Python struct pack_into(), unpack_from()
These functions allow us to pack the values into string buffer and unpack from a string buffer. These functions are introduced in version 2.5.
import struct # ctypes is imported to create a string buffer import ctypes # As shown in previous example size = struct.calcsize('hhl') print(size) # Buffer 'buff' is created from ctypes buff = ctypes.create_string_buffer(siz) # struct.pack_into() packs data into buff and it doesn't return any value # struct.unpack_from() unpacks data from buff, returns a tuple of values print(struct.pack_into('hhl', buff, 0, 5, 10, 15)) print(struct.unpack_from('hhl', buff, 0))
When we run this script, we get the following representation: That’s all for a short introduction of python struct module.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.