Как мы можем получить аннотации из файла pickle, которые сообщат нам о количестве сохраненных объектов и подробностях этого в файле pickle? - PullRequest
0 голосов
/ 12 июня 2019

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

1 Ответ

0 голосов
/ 12 июня 2019

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))
...