modul struct v Pythonu

The modul struct v Krajta umožňuje pracovat s binárními daty tím, že poskytuje funkce pro převod mezi hodnotami Pythonu a binárními daty ve stylu C. To je užitečné zejména při práci s binárními formáty souborů nebo síťovými protokoly. Mezi jeho klíčové vlastnosti patří:

  • Balení převést hodnoty Pythonu na binární data (bajty).
  • Vybalování převést binární data zpět na hodnoty Pythonu.
  • Formátovat řetězce definovat, jak jsou data sbalena/rozbalena pomocí formátových kódů (např. i pro celá čísla f pro plovoucí).

Metody v struct.pack()

1.Struct.pack(): Převádí hodnoty Pythonu do sbaleného binárního formátu. Formátovací řetězec (fmt) specifikuje rozložení komprimovaných dat a následné hodnoty (v1 v2 ...) jsou zabaleny podle tohoto formátu. Syntax:

struct.pack(fmt v1 v2 ...)

  • fmt : Formátovací řetězec, který určuje, jak budou data zabalena.
  • v1 v2 ...: Hodnoty, které budou zabaleny podle zadaného formátu.
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  )   

Výstup
b'x01x00x02x00x00x00x00x00x03x00x00x00x00x00x00x00' b'x01x00x00x00x02x00x00x00x03x00x00x00'  

Vysvětlení: 'hhl' znamená dvě krátká celá čísla (h 2 bajty každé) následovaná dlouhým (l obvykle 4 nebo 8 bajtů v závislosti na platformě). 'iii' sbalí tři 4bajtová celá čísla. Výstup je v bajtech (b'') představujících binární kódování hodnot.

2.struct.unpack(): Převádí zabalená binární data zpět na hodnoty Pythonu. Vezme formátovací řetězec (fmt) a sbalený binární řetězec a vrátí n-tici rozbalených hodnot. Syntax:

struct.unpack(fmt řetězec)

  • fmt: Formátovací řetězec, který určuje, jak mají být data rozbalena.
  • řetězec: Zabalená binární data, která je třeba rozbalit.
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  )   

Výstup
b'x01x00x02x00x05x00x00x00xbdx01x00x00x00x00x00x00' (True 2 5 445) b'x05x00x00x00x00x00x00x0033x13@' (5 2.299999952316284)  

Vysvětlení: Tento příklad nejprve zabalí boolean (?), krátký (h), celé číslo (i) a dlouhý (l) do bajtů. Poté se použije struct.unpack() k převedení zpět na hodnoty Pythonu. Druhá část sbalí dlouhé dlouhé celé číslo (q) a float (f) a poté je rozbalí zpět. Všimněte si, jak se z 2.3 stane 2,299999952... kvůli přesnosti plovoucí.

3. struct.calcsize(): Vrací velikost (v bajtech) struktury odpovídající formátovacímu řetězci. Je to užitečné pro určení, kolik místa je potřeba k uložení zabalených dat. Syntax:

struct.calcsize(fmt)

  • fmt: Formátovací řetězec, který určuje rozložení dat.
Python
   import   struct   print  (  struct  .  calcsize  (  '?hil'  ))   print  (  struct  .  calcsize  (  'qf'  ))   

Výstup
16 12  

Vysvětlení: '?hil' vyžaduje 16 bajtů a 'qf' potřebuje 12 bajtů v závislosti na zarovnání a platformě.

4. struct.pack_into() a struct.unpack_from(): Tyto metody umožňují přímo sbalit a rozbalit data do/z vyrovnávací paměti počínaje daným offsetem. Ty jsou zvláště užitečné při práci s předem přidělenými vyrovnávací paměti nebo při práci s binárními daty uloženými v paměti.

Syntaxe pro struct.pack_into():

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

  • fmt: Formátovací řetězec určující rozložení dat.
  • buffer: zapisovatelný buffer (např. ctypes.create_string_buffer).
  • offset: Počáteční pozice ve vyrovnávací paměti, kde začíná balení.
  • v1 v2 ...: Hodnoty, které mají být zabaleny do vyrovnávací paměti.

Syntaxe pro struct.unpack_from():

struct.unpack_from(fmt offset buffer=0)

  • fmt: Formátovací řetězec určující rozložení dat.
  • vyrovnávací paměť: Vyrovnávací paměť obsahující zabalená data.
  • offset: Výchozí pozice, odkud začíná vybalování (volitelné)
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  )   

Výstup
(2 2 3)  

Vysvětlení: Zde je vytvořen buffer pomocí ctypes. struct.pack_into() vloží hodnoty do této vyrovnávací paměti se zadaným posunem (v tomto případě 0). struct.unpack_from() poté načte data zpět z vyrovnávací paměti.

Účinek pořadí formátu

Pořadí formátových znaků může změnit zabalený výstup kvůli odsazení a zarovnání. To ovlivňuje jak obsah bajtů, tak velikost výsledku.

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

Výstup
b'8x00x00x00x15x14x13x12' 8 b'x15x14x13x128' 5  

Vysvětlení: 'bi' (byte int) může obsahovat výplň za byte, zatímco 'ib' (int byte) nepotřebuje to. Rozdíl velikosti (8 vs 5) ukazuje, jak zarovnání ovlivňuje rozložení paměti.

Manipulační chyby

Pokud je s struct.pack() použit nesprávný datový typ, objeví se struct.error. K bezpečnému zvládnutí takových případů použijte try-kromě.

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

Výstup

 Struct Error: required argument is not an integer   

Vysvětlení: To ukazuje zpracování chyb při použití struct. 'h' očekává krátké celé číslo, ale je zadán řetězec ('neplatný') způsobující struct.error. Blok try-except zachytí chybu a vytiskne smysluplnou zprávu.

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

Vytvořit kvíz