Кто-то сохранил более одного объекта в файле Pickle. Теперь я хочу распаковать этот файл, но как узнать, сколько объектов хранится в файле Pickle? Есть ли у них какие-либо аннотации или что-то еще, из чего мы можем получить информацию о файле Pickle?
Как мы можем получить аннотации из файла рассола, которые сообщат нам о количестве объектов, хранящихся в файле рассола, и подробности об этом?
Ответы:
Pickle не хранит эту информацию и в любом случае не поддерживает одновременное хранение более одного объекта верхнего уровня в pickle. Итак, простой ответ: это всегда один объект. Обратите внимание, что объекты могут быть тривиально вложены, поэтому вы можете, например, хранить список объектов. Это по-прежнему единый список верхнего уровня.
Если вам нужно добавить в файл несколько огурцов, вам нужно придумать свои собственные метаданные и сохранить их в дополнение к данным о огурцах.
Например, вы можете сохранить как количество объектов, так и длину потока данных для каждого объекта, обработанного отдельно, в виде числа фиксированной длины:
import pickle
import struct
with open(some_filename, 'wb') as output:
output.write(struct.pack('I', len(sequence_of_objects)))
for obj in sequence_of_objects:
pickled = pickle.dumps(obj)
output.write(struct.pack('I', len(pickled)))
output.write(pickled)
В приведенном выше примере используются 4-байтовые целые числа без знака для записи количества объектов, а также длины pickle
; отрегулируйте по мере необходимости, если количество или размеры вашего объекта могут быть такими большими.
Затем приведенное выше можно прочитать снова, скажем, с помощью функции генератора:
import pickle
import struct
def read_objects(filename):
with open(filename, 'rb') as inf:
count, = struct.unpack('I', inf.read(4))
logger.info("Reading up to %d objects from %s", count, filename)
while True:
length_bytes = inf.read(4)
if not length_bytes:
return
length, = struct.unpack('I', length_bytes)
yield pickle.loads(inf.read(length))
struct
библиотеку, это просто средство преобразования чисел на фиксированное количество байт. Вам не обязательно использовать этот метод, но вам нужен способ узнать, где заканчивается один рассол и начинается другой. Поскольку данные pickle являются двоичными, вы не можете определить это по самим данным. 15.06.2019