logo

mòdul struct en Python

El mòdul struct en Python us permet treballar amb dades binàries proporcionant funcionalitats per convertir entre valors de Python i dades binàries d'estil C. Això és especialment útil quan es tracta de formats de fitxer binaris o protocols de xarxa. Les seves característiques clau inclouen:

  • Embalatge convertir els valors de Python en dades binàries (bytes).
  • Desembalatge tornar a convertir les dades binàries en valors de Python.
  • Format de cadenes definir com s'empaqueten/descomprimeixen les dades mitjançant codis de format (per exemple, i per a nombres enters f per a flotants).

Mètodes a struct.pack()

1.Struct.pack(): Converteix els valors de Python en un format binari empaquetat. La cadena de format (fmt) especifica la disposició de les dades empaquetades i els valors posteriors (v1 v2 ...) s'embalen segons aquest format. Sintaxi:

struct.pack(fmt v1 v2...)



  • fmt : una cadena de format que especifica com s'empaquetaran les dades.
  • v1 v2...: Els valors que s'empaquetaran segons el format especificat.
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) 

Sortida
b'x01x00x02x00x00x00x00x00x03x00x00x00x00x00x00x00' b'x01x00x00x00x02x00x00x00x03x00x00x00' 

Explicació: 'hhl' significa dos nombres enters curts (h 2 bytes cadascun) seguits d'un llarg (l normalment 4 o 8 bytes depenent de la plataforma). 'iii' empaqueta tres nombres enters de 4 bytes. La sortida està en bytes (b'') que representen la codificació binària dels valors.

2.struct.unpack(): Torna a convertir les dades binàries empaquetades en valors de Python. Pren una cadena de format (fmt) i una cadena binària empaquetada i retorna una tupla de valors descomprimits. Sintaxi:

struct.unpack (cadena fmt)

  • fmt: Una cadena de format que especifica com s'han de desempaquetar les dades.
  • cadena: Les dades binàries empaquetades que cal desempaquetar.
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) 

Sortida
b'x01x00x02x00x05x00x00x00xbdx01x00x00x00x00x00x00' (True 2 5 445) b'x05x00x00x00x00x00x00x0033x13@' (5 2.299999952316284) 

Explicació: Aquest exemple empaqueta primer un booleà (?) un curt (h) un enter (i) i un llarg (l) en bytes. A continuació, s'utilitza struct.unpack() per tornar-lo a convertir en valors de Python. La segona part empaqueta un nombre enter llarg (q) i un flotant (f) i després els desempaqueta. Tingueu en compte com 2.3 es converteix en 2.299999952... a causa de la precisió de flotació.

3. struct.calcsize(): Retorna la mida (en bytes) d'una estructura corresponent a la cadena de format. És útil per determinar quant d'espai es necessita per emmagatzemar dades empaquetades. Sintaxi:

struct.calcsize(fmt)

  • fmt: una cadena de format que especifica la disposició de les dades.
Python
import struct print(struct.calcsize('?hil')) print(struct.calcsize('qf')) 

Sortida
16 12 

Explicació: '?hil' requereix 16 bytes i 'qf' necessita 12 bytes depenent de l'alineació i la plataforma.

4. struct.pack_into() i struct.unpack_from(): Aquests mètodes us permeten empaquetar i descomprimir directament dades dins/des d'un buffer a partir d'un desplaçament determinat. Són especialment útils quan es tracta de buffers de memòria prèviament assignats o quan es treballa amb dades binàries emmagatzemades a la memòria.

Sintaxi per a struct.pack_into():

struct.pack_into(fmt buffer offset v1 v2...)

com canviar la cadena a int
  • fmt: una cadena de format que especifica la disposició de les dades.
  • buffer: una memòria intermèdia que es pot escriure (per exemple, ctypes.create_string_buffer).
  • offset: la posició inicial a la memòria intermèdia on comença l'embalatge.
  • v1 v2 ...: els valors que s'han d'empaquetar a la memòria intermèdia.

Sintaxi per a struct.unpack_from():

struct.unpack_from(fmt buffer offset=0)

  • fmt: Una cadena de format que especifica la disposició de les dades.
  • buffer: El buffer que conté les dades empaquetades.
  • compensació: La posició inicial des d'on comença el desembalatge (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) 

Sortida
(2 2 3) 

Explicació: Aquí es crea un buffer utilitzant ctypes. struct.pack_into() insereix els valors en aquesta memòria intermèdia amb el desplaçament especificat (0 en aquest cas). struct.unpack_from() després llegeix les dades de la memòria intermèdia.

Efecte de l'ordre de format

L'ordre dels caràcters de format pot canviar la sortida empaquetada a causa del farciment i l'alineació. Això afecta tant el contingut en bytes com la mida del resultat.

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

Sortida
b'8x00x00x00x15x14x13x12' 8 b'x15x14x13x128' 5 

Explicació: 'bi' (byte int) pot incloure farciment després del byte, mentre que 'ib' (byte int) no ho necessita. La diferència de mida (8 vs 5) mostra com l'alineació afecta el disseny de la memòria.

Maneig d'errors

Si s'utilitza el tipus de dades incorrecte amb struct.pack() es produeix un struct.error. Utilitzeu try-except per gestionar aquests casos amb seguretat.

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

Sortida

Struct Error: required argument is not an integer  

Explicació: Això mostra el maneig d'errors quan s'utilitza struct. 'h' espera un nombre enter curt però es dóna una cadena ('invàlida') que provoca un struct.error. El bloc try-except captura l'error i imprimeix un missatge significatiu.

Referència https://docs.python.org/2/library/struct.html