struct-module in Python

De struct-module in Python stelt u in staat om met binaire gegevens te werken door functionaliteit te bieden voor het converteren tussen Python-waarden en binaire gegevens in C-stijl. Dit is vooral handig als u te maken heeft met binaire bestandsformaten of netwerkprotocollen. De belangrijkste kenmerken zijn onder meer:

  • Verpakking converteer Python-waarden naar binaire gegevens (bytes).
  • Uitpakken converteer binaire gegevens terug naar Python-waarden.
  • Tekenreeksen opmaken definieer hoe gegevens worden ingepakt/uitgepakt met behulp van formaatcodes (bijvoorbeeld i voor gehele getallen f voor floats).

Methoden in struct.pack()

1.Structuurpakket(): Het converteert Python-waarden naar een verpakt binair formaat. De formatstring (fmt) specificeert de lay-out van de ingepakte gegevens en de daaropvolgende waarden (v1 v2 ...) worden volgens dit formaat ingepakt. Syntaxis:

struct.pack(fmt v1 v2 ...)

  • fmt : Een formaattekenreeks die specificeert hoe de gegevens worden verpakt.
  • v1 v2 ...: De waarden die worden verpakt volgens het opgegeven formaat.
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  )   

Uitvoer
b'x01x00x02x00x00x00x00x00x03x00x00x00x00x00x00x00' b'x01x00x00x00x02x00x00x00x03x00x00x00'  

Uitleg: 'hhl' betekent twee korte gehele getallen (h 2 bytes elk), gevolgd door een lange (l meestal 4 of 8 bytes, afhankelijk van het platform). 'iii' bevat drie gehele getallen van 4 bytes. De uitvoer is in bytes (b'') die de binaire codering van de waarden vertegenwoordigen.

2.struct.uitpakken(): Het converteert ingepakte binaire gegevens terug naar Python-waarden. Er zijn een formatstring (fmt) en een ingepakte binaire string nodig en retourneert een tupel uitgepakte waarden. Syntaxis:

struct.unpack(fmt-tekenreeks)

  • fmt: Een formatstring die specificeert hoe de gegevens moeten worden uitgepakt.
  • snaar: De ingepakte binaire gegevens die moeten worden uitgepakt.
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  )   

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

Uitleg: In dit voorbeeld worden eerst een boolean (?), een korte (h), een geheel getal (i) en een lange (l) in bytes verpakt. Vervolgens wordt struct.unpack() gebruikt om het terug naar Python-waarden te converteren. Het tweede deel pakt een lang lang geheel getal (q) en een float (f) en pakt ze vervolgens weer uit. Merk op hoe 2,3 2,299999952 wordt... vanwege de vlotterprecisie.

3. struct.calcsize(): Het retourneert de grootte (in bytes) van een struct die overeenkomt met de formatstring. Het is handig om te bepalen hoeveel ruimte nodig is om gebundelde gegevens op te slaan. Syntaxis:

struct.calcsize(fmt)

  • fmt: Een opmaaktekenreeks die de gegevensindeling specificeert.
Python
   import   struct   print  (  struct  .  calcsize  (  '?hil'  ))   print  (  struct  .  calcsize  (  'qf'  ))   

Uitvoer
16 12  

Uitleg: '?hil' vereist 16 bytes en 'qf' heeft 12 bytes nodig, afhankelijk van de uitlijning en het platform.

4. struct.pack_into() en struct.unpack_from(): Met deze methoden kunt u gegevens direct in- en uitpakken in/uit een buffer, beginnend bij een bepaalde offset. Deze zijn vooral handig bij het omgaan met vooraf toegewezen geheugenbuffers of bij het werken met binaire gegevens die in het geheugen zijn opgeslagen.

Syntaxis voor struct.pack_into():

struct.pack_into(fmt-bufferoffset v1 v2 ...)

  • fmt: Een formaattekenreeks die de gegevensindeling specificeert.
  • buffer: Een beschrijfbare buffer (bijvoorbeeld ctypes.create_string_buffer).
  • offset: De startpositie in de buffer waar het verpakken begint.
  • v1 v2 ...: de waarden die in de buffer moeten worden ingepakt.

Syntaxis voor struct.unpack_from():

struct.unpack_from(fmt-bufferoffset=0)

  • fmt: Een opmaaktekenreeks die de gegevensindeling specificeert.
  • buffer: De buffer die de ingepakte gegevens bevat.
  • compensatie: De startpositie waar het uitpakken begint (optioneel)
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  )   

Uitvoer
(2 2 3)  

Uitleg: Hier wordt een buffer gemaakt met behulp van ctypes. struct.pack_into() voegt de waarden in deze buffer in met de opgegeven offset (in dit geval 0). struct.unpack_from() leest vervolgens de gegevens terug uit de buffer.

Effect van formaatvolgorde

De volgorde van de opmaaktekens kan de verpakte uitvoer wijzigen als gevolg van opvulling en uitlijning. Dit heeft invloed op zowel de byte-inhoud als de grootte van het resultaat.

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

Uitvoer
b'8x00x00x00x15x14x13x12' 8 b'x15x14x13x128' 5  

Uitleg: 'bi' (byte int) kan opvulling na de byte bevatten, terwijl 'ib' (int-byte) heeft het niet nodig. Het verschil in grootte (8 versus 5) laat zien hoe uitlijning de geheugenindeling beïnvloedt.

Fouten afhandelen

Als het verkeerde gegevenstype wordt gebruikt met struct.pack() treedt er een struct.error op. Gebruik try-except om dergelijke gevallen veilig af te handelen.

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

Uitvoer

 Struct Error: required argument is not an integer   

Uitleg: Dit toont de foutafhandeling bij het gebruik van struct. 'h' verwacht een kort geheel getal, maar er wordt een string ('invalid') gegeven die een struct.error veroorzaakt. Het try-except-blok vangt de fout op en drukt een betekenisvol bericht af.

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

Quiz maken