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 ...: Стойностите, които ще бъдат опаковани според посочения формат.
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: Форматиран низ, който указва как данните трябва да бъдат разопаковани.
- низ: Пакетираните двоични данни, които трябва да бъдат разопаковани.
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.
как да проверявам блокирани номера на android
3. struct.calcsize(): Той връща размера (в байтове) на структура, съответстваща на форматиращия низ. Полезно е за определяне колко място е необходимо за съхраняване на пакетирани данни. Синтаксис:
struct.calcsize(fmt)
- fmt: форматиращ низ, който указва оформлението на данните.
import struct print(struct.calcsize('?hil')) print(struct.calcsize('qf'))
Изход
16 12
Обяснение: '?hil' изисква 16 байта и 'qf' се нуждае от 12 байта в зависимост от подравняването и платформата.
4. struct.pack_into() и struct.unpack_from(): Тези методи ви позволяват директно да опаковате и разопаковате данни в/от буфер, започвайки от дадено отместване. Те са особено полезни при работа с предварително разпределени буфери на паметта или при работа с двоични данни, съхранени в паметта.
екземпляр на в java
Синтаксис за 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: Форматиран низ, указващ оформлението на данните.
- буфер: Буферът, съдържащ опакованите данни.
- офсет: Началната позиция, от която започва разопаковането (по избор)
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() след това чете данните обратно от буфера.
Ефект от реда на формата
Редът на символите за форматиране може да промени опакования изход поради подпълване и подравняване. Това засяга както съдържанието на байта, така и размера на резултата.
Pythonimport 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) показва как подравняването влияе върху оформлението на паметта.
опитайте catch в java
Грешки при обработката
Ако се използва грешен тип данни със struct.pack(), възниква struct.error. Използвайте try-except за безопасно справяне с такива случаи.
Pythonimport 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