struct модул в Python

The struct модул в Python ви позволява да работите с двоични данни, като предоставя функционалност за конвертиране между стойности на Python и двоични данни в стил C. Това е особено полезно, когато работите с двоични файлови формати или мрежови протоколи. Ключовите му характеристики включват:

  • Опаковка конвертирайте стойностите на Python в двоични данни (байтове).
  • Разопаковане преобразувайте двоични данни обратно в стойности на Python.
  • Форматиране на низове дефинирайте как данните се опаковат/разопаковат с помощта на кодове за формат (напр. i за цели числа f за числа с плаваща замък).

Методи в struct.pack()

1.Struct.pack(): Той преобразува стойностите на Python в опакован двоичен формат. Форматният низ (fmt) определя оформлението на опакованите данни и последващите стойности (v1 v2 ...) се опаковат в съответствие с този формат. Синтаксис:

struct.pack(fmt v1 v2 ...)

  • fmt : Низ за форматиране, който указва как ще бъдат пакетирани данните.
  • v1 v2 ...: Стойностите, които ще бъдат опаковани според посочения формат.
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  )   

Изход
b'x01x00x02x00x00x00x00x00x03x00x00x00x00x00x00x00' b'x01x00x00x00x02x00x00x00x03x00x00x00'  

Обяснение: 'hhl' означава две къси цели числа (h 2 байта всяко), последвани от дълго (l обикновено 4 или 8 байта в зависимост от платформата). "iii" пакетира три 4-байтови цели числа. Изходът е в байтове (b''), представляващи двоичното кодиране на стойностите.

2.struct.unpack(): Той преобразува опаковани двоични данни обратно в стойности на Python. Той приема форматиращ низ (fmt) и пакетиран двоичен низ и връща набор от неопаковани стойности. Синтаксис:

struct.unpack(fmt низ)

  • fmt: Форматиран низ, който указва как данните трябва да бъдат разопаковани.
  • низ: Пакетираните двоични данни, които трябва да бъдат разопаковани.
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  )   

Изход
b'x01x00x02x00x05x00x00x00xbdx01x00x00x00x00x00x00' (True 2 5 445) b'x05x00x00x00x00x00x00x0033x13@' (5 2.299999952316284)  

Обяснение: Този пример първо пакетира булево (?), кратко (h), цяло число (i) и дълго (l) в байтове. След това struct.unpack() се използва за преобразуването му обратно в стойности на Python. Втората част пакетира дълго дълго цяло число (q) и float (f), след което ги разопакова обратно. Забележете как 2.3 става 2.299999952... поради прецизността на float.

3. struct.calcsize(): Той връща размера (в байтове) на структура, съответстваща на форматиращия низ. Полезно е за определяне колко място е необходимо за съхраняване на пакетирани данни. Синтаксис:

struct.calcsize(fmt)

  • fmt: форматиращ низ, който указва оформлението на данните.
Python
   import   struct   print  (  struct  .  calcsize  (  '?hil'  ))   print  (  struct  .  calcsize  (  'qf'  ))   

Изход
16 12  

Обяснение: '?hil' изисква 16 байта и 'qf' се нуждае от 12 байта в зависимост от подравняването и платформата.

4. struct.pack_into() и struct.unpack_from(): Тези методи ви позволяват директно да опаковате и разопаковате данни в/от буфер, започвайки от дадено отместване. Те са особено полезни при работа с предварително разпределени буфери на паметта или при работа с двоични данни, съхранени в паметта.

Синтаксис за struct.pack_into():

struct.pack_into(fmt буфер отместване v1 v2 ...)

  • fmt: форматиращ низ, указващ оформлението на данните.
  • буфер: Буфер за запис (напр. ctypes.create_string_buffer).
  • отместване: Началната позиция в буфера, където започва опаковането.
  • v1 v2 ...: Стойностите, които трябва да бъдат пакетирани в буфера.

Синтаксис за struct.unpack_from():

struct.unpack_from(fmt буфер отместване=0)

  • fmt: Форматиран низ, указващ оформлението на данните.
  • буфер: Буферът, съдържащ опакованите данни.
  • офсет: Началната позиция, от която започва разопаковането (по избор)
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  )   

Изход
(2 2 3)  

Обяснение: Тук се създава буфер с помощта на ctypes. struct.pack_into() вмъква стойностите в този буфер при указаното отместване (0 в този случай). struct.unpack_from() след това чете данните обратно от буфера.

Ефект от реда на формата

Редът на символите за форматиране може да промени опакования изход поради подпълване и подравняване. Това засяга както съдържанието на байта, така и размера на резултата.

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

Изход
b'8x00x00x00x15x14x13x12' 8 b'x15x14x13x128' 5  

Обяснение: 'bi' (байт int) може да включва подпълване след байта, докато 'ib' (int байт) няма нужда от него. Разликата в размера (8 срещу 5) показва как подравняването влияе върху оформлението на паметта.

Грешки при обработката

Ако се използва грешен тип данни със struct.pack(), възниква struct.error. Използвайте try-except за безопасно справяне с такива случаи.

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

Изход

 Struct Error: required argument is not an integer   

Обяснение: Това показва обработка на грешки при използване на struct. 'h' очаква кратко цяло число, но е даден низ ('невалиден'), който причинява struct.error. Блокът try-except улавя грешката и отпечатва смислено съобщение.

справка https://docs.python.org/2/library/struct.html

Създаване на тест