Módulo estrutural Python

O módulo estrutural Python é utilizado para fornecer uma interface Python simples para aceder e manipular o datatype da estrutura C. Isto pode ser uma ferramenta útil se alguma vez precisar de lidar com código C e não tiver tempo para escrever ferramentas em C, uma vez que é uma linguagem de baixo nível.

Este módulo pode converter valores Python para uma estrutura em C e vice-versa. A estrutura em C é usada como um objecto de bytes Python uma vez que não há nada chamado objecto em C; apenas estruturas de dados do tamanho de um byte.

Vamos compreender como podemos usar este módulo para ter uma interface Python para estruturas em C.

Métodos do módulo estrutural Python

Neste módulo, uma vez que nos preocupamos com estruturas em C, vejamos algumas das funções que este módulo nos fornece.

estrutura.pack()

Isto é usado para embalar elementos num byte-corda Python (objecto byte). Uma vez que o modo de armazenamento é baseado em bytes, programas baseados em C podem usar a saída de pack(), de um programa Python.

Format: struct.pack(format, v1, v2, …)

v1v2, … são os valores que serão embalados no objecto byte. Eles representam os valores de campo para a estrutura C. Uma vez que uma estrutura em C com n campos deve ter exactamente n valores, os argumentos devem corresponder exactamente aos valores requeridos pelo formato.

Aqui, format refere-se ao formato da embalagem. Isto é necessário uma vez que precisamos de especificar o tipo de dados do byte-corda, uma vez que é utilizado com o código C. A tabela abaixo lista os valores mais comuns para format. Precisamos de um formato por valor para especificar o seu tipo de datatype.

c

?

>inteiro

>l

>d

s

Formato C Datatype Python type
char a string of comprimento 1
_Bool bool
h curto
long integer
i int integer
float float
double float
char string

P>Vamos compreender isto usando alguns exemplos.

O trecho abaixo armazena os 3 inteiros 1, 2 e 3 num objecto de byte usando pack(). Uma vez que o tamanho de um inteiro é de 4 bytes na minha máquina, vê-se 3 blocos de 4 bytes, que correspondem a 3 números inteiros em C.

import struct# We pack 3 integers, so 'iii' is requiredvariable = struct.pack('iii', 1, 2, 3)print(type(variable), variable)variable_2 = struct.pack('iic', 1, 2, b'A')print('\n', variable_2)

Output

<class 'bytes'> b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'b'\x01\x00\x00\x00\x02\x00\x00\x00A'

Se o tipo apropriado não for passado, a excepção struct.error será levantada pelo módulo estrutural Python.

import struct# Error!! Incorrect datatype assignmentvariable = struct.pack('ccc', 1, 2, 3)print(type(variable), variable)

Output

struct.error: char format requires a bytes object of length 1

struct.unpack()

Esta função do módulo de estrutura Python, desempacota o valor embalado na sua representação original de acordo com um formato apropriado. Isto devolve um tuple de tamanho igual ao número de valores passados desde que o objecto byte é desempacotado para dar os elementos.

Format: struct.struct.desempacotar(formato, string)

Isto desempacota o byte string de acordo com o format especificador de formato.

Este é o inverso de struct.pack(). Vamos pegar numa das antigas cordas de bytes que produzimos usando isso e tentar recuperar os valores de píton passados para ela usando unpack().

import structbyte_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-stringtuple_vals = struct.unpack('iic', byte_str)print(tuple_vals)

Output

(1, 2, b'A')

Como se pode ver, de facto, podemos obter os nossos antigos valores Python a partir deste tuple, desde que utilizemos o mesmo especificador de formato para ambos pack() e unpack().

struct.calcsize()

Esta função retorna o tamanho total da representação String da estrutura utilizando um determinado especificador de formato, para recuperar os tipos de dados e calcular o tamanho.

Format: struct.calcsize(fmt)

import structprint('C Integer Size in Bytes:', struct.calcsize('i'))print('Size of 3 characters in Bytes:', struct.calcsize('ccc'))

Output

C Integer Size in Bytes: 4Size of 3 characters in Bytes: 3

struct.pack_into()

Esta função é utilizada para embalar valores num buffer de cordas Python, disponível no módulo ctypes.

Format: struct.pack_into(fmt, buffer, offset, v1, v2, …)

Aqui, fmt refere-se ao especificador de formato, como sempre. buffer é o buffer de cordas que conterá agora os valores embalados, especificados. Também pode especificar um offset localização a partir do endereço base a partir do qual ocorrerá a embalagem.

Isto não devolve qualquer valor, e simplesmente armazena os valores na string 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 bufferbuff = 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 bufferprint(buff)

Output

<ctypes.c_char_Array_9 object at 0x7f4bccef1040>b'\x01\x00\x00\x00\x02\x00\x00\x00A'

Indeed, obtemos os nossos valores embalados na cadeia tampão.

struct.unpack_from()

Similiar a unpack(), existe uma contrapartida para desempacotar valores de uma cadeia tampão. Isto faz o inverso de struct.pack_into().

Format: struct.unpack_from(fmt, buffer, offset)

Isto irá retornar um conjunto de valores, semelhante a 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 bufferbuff = 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))

Output

(1, 2, b'A')

Conclusão

Neste artigo, aprendemos a utilizar o módulo estrutural Python para lidar com objectos de estrutura do tipo C.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *