Автор оригинала: Pankaj Kumar.
Модуль структуры Python используется для обеспечения простого интерфейса Pythonic для доступа к типу данных структуры C и управления им. Это может быть удобным инструментом, если вам когда-нибудь понадобится иметь дело с кодом на языке Си и у вас нет времени писать инструменты на языке Си, так как это язык низкого уровня.
Этот модуль может преобразовывать значения Python в структуру C и наоборот. Структура C используется в качестве объекта Python bytes, так как в C нет ничего, называемого объектом; только структуры данных размером с байт.
Давайте разберемся, как мы можем использовать этот модуль, чтобы иметь интерфейс Python к структурам C.
Методы модуля структуры Python
В этом модуле, поскольку мы имеем дело со структурами языка Си, давайте рассмотрим некоторые функции, которые предоставляет нам этот модуль.
структура.пакет()
Это используется для упаковки элементов в байтовую строку Python (байтовый объект). Поскольку режим хранения основан на байтах, программы на языке Си могут использовать вывод pack ()
из программы на Python.
Формат: struct.pack(формат, v1, v2, …)
v1
, v2
, … – это значения, которые будут упакованы в байтовый объект. Они представляют значения полей для структуры C. Поскольку структура C, имеющая n
полей, должна точно иметь n
значений, аргументы должны точно соответствовать значениям, требуемым форматом.
Здесь формат
относится к формату упаковки. Это необходимо, так как нам нужно указать тип данных байтовой строки, как это используется с кодом C. В приведенной ниже таблице перечислены наиболее распространенные значения для format
. Нам нужен один формат для каждого значения, чтобы указать его тип данных.
Формат | Тип данных C | Тип Python |
c | обуглить | строка длиной 1 |
? | _бул | тип bool |
h | короткий | целое число |
l | длинный | целое число |
i | int | целое число |
f | плыть | плыть |
d | двойной | плыть |
s | обуглить[] | строка |
Давайте разберемся в этом на нескольких примерах.
Приведенный ниже фрагмент хранит 3 целых числа 1, 2 и 3 в байтовом объекте с помощью pack()
. Поскольку размер целого числа на моей машине составляет 4 байта, вы видите 3 блока по 4 байта, которые соответствуют 3 целым числам в C.
import struct # We pack 3 integers, so 'iii' is required variable = struct.pack('iii', 1, 2, 3) print(type(variable), variable) variable_2 = struct.pack('iic', 1, 2, b'A') print('\n', variable_2)
Выход
b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00' b'\x01\x00\x00\x00\x02\x00\x00\x00A'
Если соответствующий тип не передан, исключение struct.error
будет вызвано модулем Python struct.
import struct # Error!! Incorrect datatype assignment variable = struct.pack('ccc', 1, 2, 3) print(type(variable), variable)
Выход
struct.error: char format requires a bytes object of length 1
структура.распаковать()
Эта функция модуля структуры Python распаковывает упакованное значение в его исходное представление в соответствии с соответствующим форматом. Это возвращает кортеж размером, равным количеству значений, переданных с момента распаковки байтового объекта для получения элементов.
Формат: struct.unpack(формат, строка)
Это распаковывает байт строку
в соответствии со спецификатором format
format.
Это обратная сторона struct.pack()
. Давайте возьмем одну из старых байтовых строк, которые мы создали с ее помощью, и попытаемся вернуть значения python, переданные ей с помощью unpack()
.
import struct byte_str = b'\x01\x00\x00\x00\x02\x00\x00\x00A' # Using the same format specifier as before, since # we want to get Python values for the same byte-string tuple_vals = struct.unpack('iic', byte_str) print(tuple_vals)
Выход
(1, 2, b'A')
Как вы можете видеть, действительно, мы можем вернуть наши старые значения Python из этого кортежа, при условии, что мы используем один и тот же спецификатор формата как для pack ()
, так и для unpack()
.
struct.calcsize()
Эта функция возвращает общий размер строкового представления структуры с использованием заданного спецификатора формата для извлечения типов данных и вычисления размера.
Формат: struct.calcsize(fmt)
import struct print('C Integer Size in Bytes:', struct.calcsize('i')) print('Size of 3 characters in Bytes:', struct.calcsize('ccc'))
Выход
C Integer Size in Bytes: 4 Size of 3 characters in Bytes: 3
struct.pack_into()
Эта функция используется для упаковки значений в буфер строк Python, доступный в модуле ctypes
.
Формат: struct.pack_into(fmt, буфер, смещение, v1, v2, …)
Здесь fmt
, как всегда, ссылается на спецификатор формата. buffer
– это строковый буфер, который теперь будет содержать указанные упакованные значения. Вы также можете указать смещение
местоположение от базового адреса, с которого будет происходить упаковка.
Это не возвращает никакого значения, а просто сохраняет значения в строке buffer
.
import struct import ctypes # We will create a string buffer having a size # equal to that of a struct with 'iic' values. buf_size = struct.calcsize('iic') # Create the string buffer buff = ctypes.create_string_buffer(buf_size) # struct.pack() returns the packed data struct.pack_into('iic', buff, 0, 1, 2, b'A') print(buff) # Display the contents of the buffer print(buff[:])
Выход
b'\x01\x00\x00\x00\x02\x00\x00\x00A'
Действительно, мы получаем наши упакованные значения в строке буфера.
struct.unpack_from()
Аналогично unpack()
, существует аналог для распаковки значений из строки буфера. Это делает обратное struct.pack_into()
.
Формат: struct.unpack_from(fmt, буфер, смещение)
Это вернет кортеж значений, аналогичный struct.unpack()
.
import struct import ctypes # We will create a string buffer having a size # equal to that of a struct with 'iic' values. buf_size = struct.calcsize('iic') # Create the string buffer buff = ctypes.create_string_buffer(buf_size) # struct.pack() returns the packed data struct.pack_into('iic', buff, 0, 1, 2, b'A') print(struct.unpack_from('iic', buff, 0))
Выход
(1, 2, b'A')
Вывод
В этой статье мы узнали об использовании модуля Python struct для работы с объектами структуры C-типа.