Sie können entscheiden und implementieren, wie jeder zuvor nicht-beizbare Typ gebeizt und entbeizt wird: siehe Standardbibliotheksmodul copy_reg (umbenannt in copyreg
in Python 3.*).
Im Wesentlichen müssen Sie eine Funktion bereitstellen, die eine Instanz des Typs auf ein Tupel reduziert - mit demselben Protokoll wie die reduzieren. spezielle Methode (mit dem Unterschied, dass die spezielle Methode reduce keine Argumente benötigt, da sie, wenn sie bereitgestellt wird, direkt auf dem Objekt aufgerufen wird, während die Funktion, die Sie bereitstellen, das Objekt als einziges Argument benötigt).
Das Tupel, das Sie zurückgeben, besteht in der Regel aus 2 Elementen: einem Callable und einem Tupel von Argumenten, die an das Callable übergeben werden. Das Callable muss als "sicherer Konstruktor" registriert sein oder gleichwertig über ein Attribut __safe_for_unpickling__
mit einem wahren Wert. Diese Elemente werden gepickelt, und zum Zeitpunkt des Entpickelns wird die Callable mit den angegebenen Argumenten aufgerufen und muss das entpickelte Objekt zurückgeben.
Nehmen wir zum Beispiel an, dass Sie Module nur nach Namen kommissionieren wollen, so dass das Entpacken nur ein erneutes Importieren bedeutet (d.h. nehmen wir der Einfachheit halber an, dass Sie sich nicht um dynamisch modifizierte Module, verschachtelte Pakete usw. kümmern, sondern nur um einfache Top-Level-Module). Dann:
>>> 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)>
Ich verwende die altmodische ASCII-Form von pickle, damit s
, die Zeichenkette, die den Pickle enthält, ist leicht zu untersuchen: Sie weist unpickling an, die eingebaute Importfunktion aufzurufen, mit der Zeichenkette sys
als einziges Argument. Und z
zeigt, dass dies in der Tat zu einer Rückführung der eingebauten sys
Modul als Ergebnis des Entpickelns, wie gewünscht.
Jetzt müssen Sie die Dinge etwas komplexer gestalten als nur __import__
(Sie müssen sich mit dem Speichern und Wiederherstellen von dynamischen Änderungen befassen, in einem verschachtelten Namensraum navigieren usw.), und daher müssen Sie auch die copy_reg.constructor
(und übergibt als Argument Ihre eigene Funktion, die diese Arbeit ausführt), bevor Sie copy_reg
die modulsparende Funktion, die Ihre andere Funktion zurückgibt (und, falls in einem separaten Durchlauf, auch bevor Sie die Gurken, die Sie mit der besagten Funktion hergestellt haben, entpickeln). Aber ich hoffe, dieser einfache Fall zeigt, dass es wirklich nicht viel gibt, was "an sich" kompliziert ist!-)