módulo de estructura en Python

El módulo de estructura en Pitón le permite trabajar con datos binarios al proporcionar funcionalidad para convertir entre valores de Python y datos binarios de estilo C. Esto es particularmente útil cuando se trata de formatos de archivos binarios o protocolos de red. Sus características clave incluyen:

  • Embalaje convertir valores de Python en datos binarios (bytes).
  • Desembalaje convertir datos binarios nuevamente en valores de Python.
  • Formatear cadenas defina cómo se empaquetan/desempaquetan los datos usando códigos de formato (por ejemplo, i para enteros f para flotantes).

Métodos en struct.pack()

1.Estructura.paquete(): Convierte valores de Python a un formato binario empaquetado. La cadena de formato (fmt) especifica el diseño de los datos empaquetados y los valores posteriores (v1 v2...) se empaquetan de acuerdo con este formato. Sintaxis:

estructura.pack(fmt v1 v2...)

  • fmt : una cadena de formato que especifica cómo se empaquetarán los datos.
  • v1 v2...: Los valores que se empaquetarán según el formato especificado.
Python
   import   struct   # pack values into binary   var   =   struct  .  pack  (  'hhl'     1     2     3  )   print  (  var  )   var   =   struct  .  pack  (  'iii'     1     2     3  )   print  (  var  )   

Producción
b'x01x00x02x00x00x00x00x00x03x00x00x00x00x00x00x00' b'x01x00x00x00x02x00x00x00x03x00x00x00'  

Explicación: 'hhl' significa dos enteros cortos (h 2 bytes cada uno) seguidos de uno largo (normalmente 4 u 8 bytes dependiendo de la plataforma). 'iii' empaqueta tres enteros de 4 bytes. La salida está en bytes (b'') que representan la codificación binaria de los valores.

2.struct.unpack(): Convierte datos binarios empaquetados nuevamente en valores de Python. Toma una cadena de formato (fmt) y una cadena binaria empaquetada y devuelve una tupla de valores desempaquetados. Sintaxis:

estructura.unpack(cadena fmt)

  • fmt: Una cadena de formato que especifica cómo se deben descomprimir los datos.
  • cadena: Los datos binarios empaquetados que deben descomprimirse.
Python
   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  )   

Producción
b'x01x00x02x00x05x00x00x00xbdx01x00x00x00x00x00x00' (True 2 5 445) b'x05x00x00x00x00x00x00x0033x13@' (5 2.299999952316284)  

Explicación: Este ejemplo primero empaqueta un booleano (?), un corto (h), un entero (i) y un largo (l) en bytes. Luego se usa struct.unpack() para convertirlo nuevamente a valores de Python. La segunda parte empaqueta un entero largo (q) y un flotante (f) y luego los descomprime. Observe cómo 2.3 se convierte en 2.299999952... debido a la precisión flotante.

3. estructura.calcsize(): Devuelve el tamaño (en bytes) de una estructura correspondiente a la cadena de formato. Es útil para determinar cuánto espacio se requiere para almacenar datos empaquetados. Sintaxis:

estructura.calcsize(fmt)

  • fmt: una cadena de formato que especifica el diseño de los datos.
Python
   import   struct   print  (  struct  .  calcsize  (  '?hil'  ))   print  (  struct  .  calcsize  (  'qf'  ))   

Producción
16 12  

Explicación: '?hil' requiere 16 bytes y 'qf' necesita 12 bytes dependiendo de la alineación y la plataforma.

4. struct.pack_into() y struct.unpack_from(): Estos métodos le permiten empaquetar y descomprimir datos directamente en/desde un búfer comenzando en un desplazamiento determinado. Estos son particularmente útiles cuando se trata de buffers de memoria preasignados o cuando se trabaja con datos binarios almacenados en la memoria.

Sintaxis de struct.pack_into():

struct.pack_into(desplazamiento del buffer fmt v1 v2...)

  • fmt: una cadena de formato que especifica el diseño de los datos.
  • buffer: Un buffer grabable (por ejemplo, ctypes.create_string_buffer).
  • desplazamiento: la posición inicial en el búfer donde comienza el embalaje.
  • v1 v2...: Los valores que se empaquetarán en el búfer.

Sintaxis de struct.unpack_from():

struct.unpack_from (desplazamiento del búfer fmt = 0)

  • fmt: Una cadena de formato que especifica el diseño de los datos.
  • buffer: El búfer que contiene los datos empaquetados.
  • compensar: La posición inicial desde donde comienza el desembalaje (opcional)
Python
   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  )   

Producción
(2 2 3)  

Explicación: Aquí se crea un búfer usando ctypes. estructura.pack_into() inserta los valores en este búfer en el desplazamiento especificado (0 en este caso). estructura.unpack_from() luego lee los datos del búfer.

Efecto del orden de formato

El orden de los caracteres de formato puede cambiar la salida empaquetada debido al relleno y la alineación. Esto afecta tanto al contenido de bytes como al tamaño del 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'  ))   

Producción
b'8x00x00x00x15x14x13x12' 8 b'x15x14x13x128' 5  

Explicación: 'bi' (byte int) podría incluir relleno después del byte, mientras que 'ib' (byte entero) no lo necesita. La diferencia de tamaño (8 frente a 5) muestra cómo la alineación afecta el diseño de la memoria.

Errores de manejo

Si se utiliza el tipo de datos incorrecto con struct.pack(), se produce un error de estructura. Utilice try-except para manejar estos casos de forma segura.

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  }  '  )   

Producción

 Struct Error: required argument is not an integer   

Explicación: Esto muestra el manejo de errores al usar struct. 'h' espera un número entero corto pero se proporciona una cadena ('inválida') que provoca un error de estructura. El bloque try-except captura el error e imprime un mensaje significativo.

Referencia https://docs.python.org/2/library/struct.html

Crear cuestionario