Вы можете решить и реализовать как любой ранее unpicklable типа получает маринованный и unpickled: см стандартной библиотеки модуль copy_reg (переименован в copyreg
в Python 3. *).
По существу, вам необходимо предоставить функцию, которая, учитывая экземпляр типа, сводит его к кортежу - с тем же протоколом, что и специальный метод reduce (за исключением того, что специальный метод уменьшения не принимает аргументов, поскольку при условии, что он вызван непосредственно на объект, а предоставленная вами функция примет объект в качестве единственного аргумента).
Как правило, кортеж, который вы возвращаете, имеет 2 элемента: вызываемый и кортеж аргументов, чтобы передать его. Вызываемый должен быть зарегистрирован как «безопасный конструктор» или эквивалентен атрибуту __safe_for_unpickling__
с истинным значением. Эти элементы будут мариноваться, и в разное время вызываемый будет вызываться с заданными аргументами и должен возвращать неопубликованный объект.
Например, предположим, что вы хотите просто рассортировать модули по имени, так что их размножение просто означает их повторное импортирование (т. Е. Предположим для простоты, что вам не нужны динамически модифицированные модули, вложенные пакеты и т. Д., Просто простые модули верхнего уровня).Тогда:
>>> import sys, pickle, copy_reg
>>> def savemodule(module):
... return __import__, (module.__name__,)
...
>>> copy_reg.pickle(type(sys), savemodule)
>>> s = pickle.dumps(sys)
>>> s
"c__builtin__\n__import__\np0\n(S'sys'\np1\ntp2\nRp3\n."
>>> z = pickle.loads(s)
>>> z
<module 'sys' (built-in)>
Я использую старомодный форму ASCII из маринада, так что s
, строка, содержащая маринад, легко изучить: она инструктирует unpickling вызвать встроенную функцию импорта, с строка sys
в качестве единственного аргумента. И z
показывает, что это действительно возвращает нам встроенный модуль sys
в результате рассыпания по желанию.
Теперь вам нужно сделать что-то более сложным, чем просто __import__
(вам придется иметь дело с сохранением и восстановлением динамических изменений, перемещением вложенного пространства имен и т. Д.), И, следовательно, вам также придется вызовите copy_reg.constructor
(передавая в качестве аргумента свою собственную функцию, которая выполняет эту работу) перед тем, как вы выполните copy_reg
функцию сохранения модуля, которая возвращает вашу другую функцию (и, если в отдельном прогоне, также перед тем, как вы разложите эти соленые огурцы, созданные с помощью указанной функции). Но я надеюсь, что эти простые случаи помогают показать, что в этом нет ничего особенного, что «по-своему» сложно! -)
Java Beans .. Python Pickles .. Я хотел бы задушить ботаников, которые придумали это cutesy stuff –