módulo struct em Python
O módulo de estrutura em Pitão permite que você trabalhe com dados binários, fornecendo funcionalidade para conversão entre valores Python e dados binários no estilo C. Isto é particularmente útil ao lidar com formatos de arquivos binários ou protocolos de rede. Seus principais recursos incluem:
- Embalagem converter valores Python em dados binários (bytes).
- Desempacotando converter dados binários de volta em valores Python.
- Formatar cadeias de caracteres definir como os dados são compactados/descompactados usando códigos de formato (por exemplo, i para inteiros f para flutuantes).
Métodos em struct.pack()
1.Estrutura.pack(): Ele converte valores Python em um formato binário compactado. A string de formato (fmt) especifica o layout dos dados compactados e os valores subsequentes (v1 v2 ...) são compactados de acordo com este formato. Sintaxe:
struct.pack(fmt v1 v2 ...)
- fmt : uma string de formato que especifica como os dados serão compactados.
- v1v2...: Os valores que serão compactados de acordo com o formato especificado.
import struct # pack values into binary var = struct . pack ( 'hhl' 1 2 3 ) print ( var ) var = struct . pack ( 'iii' 1 2 3 ) print ( var )
Saída
b'x01x00x02x00x00x00x00x00x03x00x00x00x00x00x00x00' b'x01x00x00x00x02x00x00x00x03x00x00x00'
Explicação: 'hhl' significa dois inteiros curtos (h 2 bytes cada) seguidos por um longo (geralmente 4 ou 8 bytes dependendo da plataforma). 'iii' empacota três inteiros de 4 bytes. A saída está em bytes (b'') representando a codificação binária dos valores.
2.struct.unpack(): Ele converte dados binários compactados de volta em valores Python. Ele pega uma string de formato (fmt) e uma string binária compactada e retorna uma tupla de valores descompactados. Sintaxe:
struct.unpack (string fmt)
- mt: Uma string de formato que especifica como os dados devem ser descompactados.
- corda: Os dados binários compactados que precisam ser descompactados.
import struct var = struct . pack ( '?hil' True 2 5 445 ) print ( var ) tup = struct . unpack ( '?hil' var ) print ( tup ) var = struct . pack ( 'qf' 5 2.3 ) print ( var ) tup = struct . unpack ( 'qf' var ) print ( tup )
Saída
b'x01x00x02x00x05x00x00x00xbdx01x00x00x00x00x00x00' (True 2 5 445) b'x05x00x00x00x00x00x00x0033x13@' (5 2.299999952316284)
Explicação: Este exemplo primeiro empacota um booleano (?) um short (h), um inteiro (i) e um long (l) em bytes. Então struct.unpack() é usado para convertê-lo novamente em valores Python. A segunda parte empacota um inteiro longo (q) e um float (f) e depois os descompacta de volta. Observe como 2,3 se torna 2,299999952... devido à precisão do float.
3. struct.calcsize(): Ele retorna o tamanho (em bytes) de uma estrutura correspondente à string de formato. É útil para determinar quanto espaço é necessário para armazenar dados compactados. Sintaxe:
estrutura.calcsize(fmt)
- fmt: Uma string de formato que especifica o layout dos dados.
import struct print ( struct . calcsize ( '?hil' )) print ( struct . calcsize ( 'qf' ))
Saída
16 12
Explicação: '?hil' requer 16 bytes e 'qf' precisa de 12 bytes dependendo do alinhamento e da plataforma.
4. struct.pack_into() e struct.unpack_from(): Esses métodos permitem compactar e descompactar dados diretamente em/de um buffer começando em um determinado deslocamento. Eles são particularmente úteis ao lidar com buffers de memória pré-alocados ou ao trabalhar com dados binários armazenados na memória.
Sintaxe para struct.pack_into():
struct.pack_into (deslocamento do buffer fmt v1 v2 ...)
- fmt: Uma string de formato que especifica o layout dos dados.
- buffer: um buffer gravável (por exemplo, ctypes.create_string_buffer).
- offset: A posição inicial no buffer onde o empacotamento começa.
- v1 v2 ...: Os valores a serem compactados no buffer.
Sintaxe para struct.unpack_from():
struct.unpack_from(deslocamento do buffer fmt = 0)
- mt: Uma string de formato que especifica o layout dos dados.
- buffer: O buffer que contém os dados compactados.
- desvio: A posição inicial de onde começa a desembalagem (opcional)
import struct import ctypes # Allocate buffer size = struct . calcsize ( 'hhl' ) buff = ctypes . create_string_buffer ( size ) # Pack into buffer struct . pack_into ( 'hhl' buff 0 2 2 3 ) # Unpack from buffer res = struct . unpack_from ( 'hhl' buff 0 ) print ( res )
Saída
(2 2 3)
Explicação: Aqui um buffer é criado usando ctypes. struct.pack_into() insere os valores neste buffer no deslocamento especificado (0 neste caso). struct.unpack_from() em seguida, lê os dados do buffer.
Efeito da ordem de formato
A ordem dos caracteres de formato pode alterar a saída compactada devido ao preenchimento e ao alinhamento. Isso afeta o conteúdo de bytes e o tamanho do resultado.
Python import struct var = struct . pack ( 'bi' 56 0x12131415 ) print ( var ) print ( struct . calcsize ( 'bi' )) var = struct . pack ( 'ib' 0x12131415 56 ) print ( var ) print ( struct . calcsize ( 'ib' ))
Saída
b'8x00x00x00x15x14x13x12' 8 b'x15x14x13x128' 5
Explicação: 'bi' (byte int) pode incluir preenchimento após o byte, enquanto 'ib' (int byte) não precisa disso. A diferença de tamanho (8 vs 5) mostra como o alinhamento afeta o layout da memória.
Tratamento de erros
Se o tipo de dados errado for usado com struct.pack() ocorre um struct.error. Use try-except para lidar com esses casos com segurança.
Python import struct try : struct . pack ( 'h' 'invalid' ) # Wrong type 'invalid' is a string but 'h' expects an integer except struct . error as e : print ( f 'Struct Error: { e } ' )
Saída
Struct Error: required argument is not an integer
Explicação: Isso mostra o tratamento de erros ao usar struct. 'h' espera um número inteiro curto, mas uma string ('inválida') é fornecida causando um struct.error. O bloco try-except captura o erro e imprime uma mensagem significativa.
Referência https://docs.python.org/2/library/struct.html
Criar questionário