2015-08-11 2 views
0

Я хотел бы законсервировать-дамп объекта, как это:Рассол дамп объект ссылается модуль

import module_A 
import module_B 

class SomeClass(object): 
    def __init__(self, the_module): 
    self.module = the_module 
    self.some_other_members = whatever 

x = SomeClass(module_A) 

не допускается, и ошибка в том, что я не могу сбросить модуль. В этом случае меня не интересует фактический сброс модуля. Однако, какой модуль использует объект. Поэтому я хотел бы сбросить некоторый идентификатор модуля таким образом, чтобы на __setstate__ я мог указать self.module на правый модуль. Какие идентификаторы я должен использовать так, чтобы на __setstate__ я могу найти правильный модуль по этому идентификатору? Могут быть много возможных модулей, и класс SomeClass теперь знает, какие из них есть.

UPDATE:

Извините сообщение об ошибке, мы обнаружили, когда мы использовали cPickle. Обычная pickle не имеет этой проблемы, и, как отметил Майк, dill поддерживает также травильные модули. Окончательное решение, которое я использую, приведено здесь: https://mail.python.org/pipermail/python-ideas/2013-July/021959.html.

ответ

0

Я думаю, что вы можете делать то, что вы хотите с dill, что обеспечивает лучшие сериализации, чем pickle.

>>> import dill 
>>> import numpy 
>>> 
>>> import math 
>>> 
>>> class SomeClass(object): 
... def __init__(self, module): 
...  self.module = module 
...  self.other = lambda x: numpy.arange(3) 
... 
>>> # save the class instance 
>>> x = SomeClass(math) 
>>> _x = dill.dumps(x) 
>>> 
>>> # delete a bunch of stuff 
>>> del SomeClass 
>>> del math 
>>> import sys 
>>> del sys.modules['math'] 
>>> del x 
>>> 
>>> # unpickle 
>>> x = dill.loads(_x) 
>>> x.module 
>>> x.module.sin(x.other(0)[0]) 
0.0 
+0

BTW: Я автор 'dill', поэтому, если вы обнаружите, что это не работает для вашего дела, дайте мне знать. –

+0

Спасибо, Майк. Я использую это решение в https://mail.python.org/pipermail/python-ideas/2013-July/021959.html, но приятно знать, что укроп может это сделать. Используется ли такая же техника? Кстати, я обнаружил, что сериализованные строки из протокола укропа 2 в несколько раз больше, чем протокол cPickle 2. Есть ли способ уменьшить размер в дампах укропа, но поддерживать скорость загрузки? – shaoyl85

+0

Ссылка, которую вы предоставляете, является одним из способов, которым «укроп» сериализует модуль. Для некоторых объектов (например, классов, функций и методов) вы можете изменить то, что «окунь», изменив «dill.settings». 'dill.settings ['byref'] = True' будет более точно имитировать то, что делает' cPickle'. 'dill.settings ['recurse'] = True' будет включать только соответствующие зависимости от' globals', а по умолчанию - все. Соленые огурцы более длинные, потому что для обработки большего количества случаев нужно раскрыть больше инструкций. –

0

Ну, вряд ли полный ответ, но когда я взглянул на модуль, который я установил на «фиктивный», тестовый объект, я получаю.

print dummy.module.__file__ 

выход

'lib/utils.pyc' 

и некоторые инспекции:

>>> type(dummy.module) 
<type 'module'> 
>>> type(dummy.module.__file__) 
<type 'str'> 
>>> 

Может быть, вы можете сохранить "Библиотека/утилиты" из выше (во время вашего __getstate__), а затем сделать соответствующий импорт заклинания, чтобы вернуть ваш модуль во время __setstate__?

Вы не должны беспокоиться о импорте вообще, если модуль уже загружен:

dummy.module2 = sys.modules["lib.utils"] 
Смежные вопросы