logo

struct modul u Pythonu

The strukturni modul u Piton omogućuje vam rad s binarnim podacima pružajući funkcionalnost za pretvorbu između Python vrijednosti i C-style binarnih podataka. Ovo je osobito korisno kada se radi o binarnim formatima datoteka ili mrežnim protokolima. Njegove ključne karakteristike uključuju:

  • Pakiranje pretvoriti Python vrijednosti u binarne podatke (bajtove).
  • Raspakiranje pretvoriti binarne podatke natrag u Python vrijednosti.
  • Format nizova definirajte kako se podaci pakiraju/otpakiraju pomoću kodova formata (npr. i za cijele brojeve f za float).

Metode u struct.pack()

1.Struct.pack(): Pretvara Python vrijednosti u upakirani binarni format. Niz formata (fmt) specificira raspored pakiranih podataka i sljedeće vrijednosti (v1 v2 ...) pakirane su u skladu s ovim formatom. Sintaksa:

struct.pack(fmt v1 v2 ...)



  • fmt : niz formata koji određuje kako će podaci biti pakirani.
  • v1 v2 ...: Vrijednosti koje će biti pakirane prema navedenom formatu.
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) 

Izlaz
b'x01x00x02x00x00x00x00x00x03x00x00x00x00x00x00x00' b'x01x00x00x00x02x00x00x00x03x00x00x00' 

Objašnjenje: 'hhl' znači dva kratka cijela broja (h 2 bajta svaki) iza kojih slijedi dugi (l obično 4 ili 8 bajta ovisno o platformi). 'iii' pakira tri cijela broja od 4 bajta. Izlaz je u bajtovima (b'') koji predstavljaju binarno kodiranje vrijednosti.

2.struct.unpack(): Pretvara upakirane binarne podatke natrag u Python vrijednosti. Uzima formatni niz (fmt) i pakirani binarni niz i vraća torku nepakiranih vrijednosti. Sintaksa:

struct.unpack(fmt niz)

  • fmt: Niz formata koji određuje kako se podaci trebaju raspakirati.
  • niz: Zapakirani binarni podaci koje je potrebno raspakirati.
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) 

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

Obrazloženje: Ovaj primjer prvo pakira booleov (?) kratki (h), cijeli (i) i dugi (l) u bajtove. Zatim se struct.unpack() koristi za pretvaranje natrag u Python vrijednosti. Drugi dio pakira dugi dugi cijeli broj (q) i float (f), a zatim ih otpakira natrag. Primijetite kako 2,3 postaje 2,299999952... zbog preciznosti float-a.

3. struct.calcsize(): Vraća veličinu (u bajtovima) strukture koja odgovara nizu formata. Korisno je za određivanje koliko je prostora potrebno za pohranjivanje pakiranih podataka. Sintaksa:

struct.calcsize(fmt)

  • fmt: niz formata koji specificira raspored podataka.
Python
import struct print(struct.calcsize('?hil')) print(struct.calcsize('qf')) 

Izlaz
16 12 

Objašnjenje: '?hil' zahtijeva 16 bajtova i 'qf' treba 12 bajtova ovisno o poravnanju i platformi.

4. struct.pack_into() i struct.unpack_from(): Ove vam metode omogućuju izravno pakiranje i raspakiranje podataka u/iz međuspremnika počevši od zadanog pomaka. Oni su osobito korisni kada se radi s unaprijed dodijeljenim međuspremnicima ili kada se radi s binarnim podacima pohranjenim u memoriji.

Sintaksa za struct.pack_into():

struct.pack_into(fmt pomak međuspremnika v1 v2 ...)

  • fmt: niz formata koji specificira raspored podataka.
  • međuspremnik: međuspremnik za pisanje (npr. ctypes.create_string_buffer).
  • pomak: početni položaj u međuspremniku gdje počinje pakiranje.
  • v1 v2 ...: Vrijednosti koje treba upakirati u međuspremnik.

Sintaksa za struct.unpack_from():

struct.unpack_from(fmt pomak međuspremnika=0)

  • fmt: Niz formata koji specificira raspored podataka.
  • pufer: Međuspremnik koji sadrži zapakirane podatke.
  • pomak: Početna pozicija odakle počinje raspakiranje (nije obavezno)
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) 

Izlaz
(2 2 3) 

Obrazloženje: Ovdje se međuspremnik stvara pomoću ctype-ova. struct.pack_into() umeće vrijednosti u ovaj međuspremnik na navedenom pomaku (0 u ovom slučaju). struct.unpack_from() zatim čita podatke natrag iz međuspremnika.

Učinak redoslijeda formata

Redoslijed znakova formata može promijeniti upakirani izlaz zbog ispune i poravnanja. To utječe i na sadržaj bajtova i na veličinu rezultata.

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

Izlaz
b'8x00x00x00x15x14x13x12' 8 b'x15x14x13x128' 5 

Objašnjenje: 'bi' (bajt int) može uključivati ​​punjenje nakon bajta dok 'ib' (int bajt) ne treba. Razlika u veličini (8 prema 5) pokazuje kako poravnanje utječe na raspored memorije.

Pogreške u rukovanju

Ako se koristi pogrešan tip podataka sa struct.pack(), javlja se struct.error. Koristite try-except za sigurno rješavanje takvih slučajeva.

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

Izlaz

Struct Error: required argument is not an integer  

Obrazloženje: Ovo pokazuje rukovanje pogreškama kada se koristi struct. 'h' očekuje kratki cijeli broj, ali je dan niz ('nevažeći') koji uzrokuje struct.error. Blok try-except bilježi pogrešku i ispisuje smislenu poruku.

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

kako pretvoriti niz u cijeli broj u Javi