Сообщить об ошибке.

Примеры использования модуля struct

Ниже представлены несколько общих примеров использования функции модуля struct.

Примеры использования:

В этом примере строка формата вызывает длинное целое значение, двухбайтовую строку и число с плавающей запятой. В строку формата включены пробелы для разделения индикаторов типа, которые будут проигнорированы при компиляции.

import struct
import binascii

values = (1, 'ab'.encode('utf-8'), 2.7)
s = struct.Struct('@ I 2s f')
packed_data = s.pack(*values)
print('Строка формата:', s.format)
print('Использовано памяти:', s.size, 'bytes')
print('Упакованное значение:', binascii.hexlify(packed_data))

# Строка формата: I 2s f
# Использовано памяти: 12 bytes
# Упакованное значение: b'0100000061620000cdcc2c40'

Теперь достанем данные из упакованного представления.

import struct
import binascii

packed_data = binascii.unhexlify(b'0100000061620000cdcc2c40')

s = struct.Struct('@ I 2s f')
unpacked_data = s.unpack(packed_data)
print('Оригинальное значение:', unpacked_data)

# Оригинальное значение: (1, b'ab', 2.700000047683716)

Распакованные данные можно присваивать переменным используя операцию "присвоение распаковкой" или оборачивая результат в именованный кортеж:

>>> import struct
>>> record = b'raymond   \x32\x12\x08\x01\x08'
# присвоение распаковкой
>>> name, serialnum, school, gradelevel = struct.unpack('< 10s H H b', record)
>>> print(name, serialnum, school, gradelevel)
# b'raymond   ' 4658 264 8

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
# оборачиваем результат в именованный кортеж
>>> Student._make(struct.unpack('< 10s H H b', record))
# Student(name=b'raymond   ', serialnum=4658, school=264, gradelevel=8)

Работа с двоичными упакованными данными обычно резервируется для чувствительных к производительности ситуаций или для передачи данных в модули расширения и из них. Эти случаи можно оптимизировать, избегая затрат на выделение нового буфера для каждой упакованной структуры. Методы struct.pack_into() и struct.unpack_from() поддерживают прямую запись в заранее выделенные буферы.

import array, ctypes, binascii, struct

s = struct.Struct('@I 2s f')
values = (1, 'ab'.encode('utf-8'), 2.7)
print('Original:', values)

b = ctypes.create_string_buffer(s.size)

a = array.array('b', b'\0' * s.size)
print('\nBefore  :', binascii.hexlify(a))
s.pack_into(a, 0, *values)
print('After     :', binascii.hexlify(a))
print('Unpacked:', s.unpack_from(a, 0))

# Original: (1, b'ab', 2.7)
# 
# Before  : b'000000000000000000000000'
# After     : b'0100000061620000cdcc2c40'
# Unpacked: (1, b'ab', 2.700000047683716)

Атрибут size объекта Struct сообщает нам, насколько большим должен быть буфер.