Ошибка рассола утверждает идентификатор (obj) не в self.memo

Сейчас я использую dill (расширенную версию pickle). Я хочу сериализовать свой объект, но получаю эту ошибку:

/usr/lib/python2.7/pickle.pyc in memoize(self, obj)
    242         if self.fast:
    243             return
--> 244         assert id(obj) not in self.memo
    245         memo_len = len(self.memo)
    246         self.write(self.put(memo_len))

Может ли кто-нибудь сказать мне, что эта ошибка допустила или как я могу это решить?


person psuedobot    schedule 11.08.2014    source источник
comment
Можете ли вы показать нам код, который выдает ошибку?   -  person enrico.bacis    schedule 11.08.2014
comment
На первый взгляд, dill нарушает инвариант pickle; рекурсивные структуры не должны приводить к повторному маринованию циклических ссылок. self.memo отслеживает то, что уже было промариновано ранее.   -  person Martijn Pieters    schedule 11.08.2014
comment
@enrico.bacis Мне жаль, что код очень длинный и состоит из нескольких файлов ... поэтому я почти не показываю вам ... но я использую фреймворк Numpy, Scipy, Theano ...   -  person psuedobot    schedule 11.08.2014
comment
@MartijnPieters, так что я должен попытаться найти циклические ссылки, которые вызывают эту проблему?   -  person psuedobot    schedule 11.08.2014
comment
@psuedobot: возможно; Я не знаю dill, но утверждение id(obj) not in self.memo срабатывает, если id(obj) уже было замечено.   -  person Martijn Pieters    schedule 11.08.2014
comment
@MartijnPieters: я dill автор. Это просто большая коллекция использования copy_reg для разных объектов, и я не нарушаю никаких инвариантов pickle… Тем не менее, я делаю несколько обходных путей, чтобы всевозможные объекты добавлялись в memo из pickle при импорте dill. В добавлении к памятке нет дублирования, если только вы не делаете что-то странное, например, import pickle, затем copy_reg что-то еще, затем import dill — и, вероятно, во многих случаях это даже нормально.   -  person Mike McKerns    schedule 11.08.2014
comment
@MikeMcKerns: Верно; У меня совсем не было времени заглянуть во dill внутренности. Звучит так, как будто ОП должен попытаться создать минимальный пример, который вызывает проблему?   -  person Martijn Pieters    schedule 11.08.2014
comment
@MartijnPieters: абсолютно.   -  person Mike McKerns    schedule 11.08.2014
comment
@MartijnPieters Я уже пытался посмотреть свой код, но я не импортировал рассол. Я только импортирую укроп.   -  person psuedobot    schedule 12.08.2014
comment
Так? dill использует pickle; но последуйте совету Майка.   -  person Martijn Pieters    schedule 12.08.2014
comment
@MartijnPieters теперь я уже включаю трассировку. И прямо перед тем, как утверждение не удалось, он показал, что рассол пытался сериализоваться в строке def __init___(self, ...)   -  person psuedobot    schedule 12.08.2014
comment
@psuedobot Было бы полезно, если бы вы обновили свой вопрос, чтобы показать трассировку или результаты любого из detect методов, которые вы пробовали, как показано ниже в моем посте. Гораздо труднее помочь, не видя того, что видишь.   -  person Mike McKerns    schedule 12.08.2014


Ответы (1)


Без публикации сокращенной версии вашего кода трудно помочь. Однако у dill есть несколько встроенных методов обнаружения. Посмотрите на dill.detect.

>>> # trace dill's pickling of objects, by printing out step by step trace 
>>> dill.detect.trace(True)

Или при осмотре объекта.

>>> dill.detect.badobjects(yourfailingobject, depth=1)

Также есть dill.detect.badtypes и так далее.

Или вы можете проследить, как объекты соотносятся друг с другом с помощью dill.detect.parent, dill.detect.children, dill.detect.reference и так далее.

Вот пример использования dill (плюс objgraph для визуализации) для отслеживания циклических ссылок. https://github.com/uqfoundation/dill/issues/58

Также есть большой список всего того, что dill не умеет сериализовать в dill._objects -- по крайней мере, первые 15 разделов стандартной библиотеки python, а также некоторые другие.

person Mike McKerns    schedule 11.08.2014
comment
теперь я попробовал dill.detect.trace(True). И последняя строка INFO перед ошибкой указывает на строку, в которой я закодировал def __init__(self, a, b, c) из объекта класса, который я хочу сериализовать. - person psuedobot; 12.08.2014
comment
@psuedobot: из вашего комментария выше сложно сказать, что происходит - person Mike McKerns; 04.09.2014