Рубрики
Без рубрики

Модуль структуры Python

Модуль структуры Python используется для обеспечения простого интерфейса Pythonic для доступа к типу данных структуры C и управления им. Это может быть удобным инструментом, если вы когда-нибудь

Автор оригинала: 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-типа.

Рекомендации