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 buffer offset v1 v2 ...)

  • fmt: рядок формату, що вказує макет даних.
  • buffer: Буфер для запису (наприклад, ctypes.create_string_buffer).
  • зсув: початкова позиція в буфері, де починається пакування.
  • v1 v2 ...: значення, які потрібно запакувати в буфер.

Синтаксис для struct.unpack_from():

struct.unpack_from(fmt buffer offset=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' (цілий байт) не потребує цього. Різниця розмірів (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' очікує коротке ціле число, але надається рядок ('invalid'), що викликає struct.error. Блок try-except фіксує помилку та друкує змістовне повідомлення.

довідка https://docs.python.org/2/library/struct.html

Створіть вікторину