Получи случайную криптовалюту за регистрацию!

Есть один интересный момент с запаковкой строк. >>> struct.pa | Python Заметки

Есть один интересный момент с запаковкой строк.

>>> struct.pack(f'=6s', b'python')
b'python'
>>> 'python'.encode()
b'python'

Хммм..., struct создает тип bytest но при этом для строки просит тоже bytes. На выходе получаем опять bytes без изменений. В чем логика? Ведь ничего же не поменялось! Зачем тогда нам вообще нужен struct если encode делает тоже самое?

Если вам требуется записать просто одну строку какой-то рандомной длины, то паковка тут не нужна. Можете писать любые байты в файл как угодно без запаковки.
А смысл паковки в том, что с помощью формата мы гарантируем правильную длину всех частей записываемых данных.

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

>>> struct.pack(f'=3s', b'python')
b'pyt'
>>> struct.pack(f'=10s', b'python')
b'python\x00\x00\x00\x00'

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

128 байт : какой-то заголовок (str)
8 байт : количество элементов (int)
[4 байта] : массив данных (тип float до конца файла по 4 байта)

Теперь мы знаем как записывать и считывать этот файл, у нас есть его спецификация. Просто берëм нужный диапазон байт и распаковываем в нужный тип данных.
Если мы хоть на один байт сместимся, то данные распакуются некорректно.

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

data1 = [...]
data2 = [...]
struct.pack(f'=Q{len(data1)}i', len(data1), data1)
struct.pack(f'=Q{len(data2)}i', len(data2), data2)

Начиная с начала файлы мы точно знаем что следующие 8 байт (Q = unsigned long long) это число с количеством элементов, записанных сразу после него. И точно знаем где находится следующий блок данных.

Еще раз, помимо преобразования разных типов в байты, модуль struct занимается форматированием или разметкой данных в файле. Именно это и означает что разметка находится вне файла с данными. И это критически важный момент при создании бинарных файлов!

#libs