Vous pouvez décider et mettre en œuvre la façon dont tout type précédemment unpicklable se décapée et unpickled: voir bibliothèque standard module copy_reg (renommé en copyreg
en Python 3. *). Essentiellement, vous devez fournir une fonction qui, donnée une instance du type, la réduit à un tuple - avec le même protocole que la méthode spéciale reduce (sauf que la méthode spéciale reduce ne prend aucun argument, puisque quand à condition qu'il soit appelé directement sur l'objet, alors que la fonction que vous fournissez prendra l'objet comme seul argument).
Typiquement, le tuple que vous renvoyez contient 2 éléments: un appelable et un tuple d'arguments à lui transmettre. L'appelable doit être enregistré en tant que "constructeur sûr" ou avoir de manière équivalente un attribut __safe_for_unpickling__
avec une valeur vraie. Ces éléments seront décapés, et au moment du décubitus l'appelable sera appelé avec les arguments donnés et doit renvoyer l'objet non sélectionné. Par exemple, supposons que vous souhaitiez simplement sélectionner les modules par leur nom, de sorte que leur suppression signifie simplement leur réimportation (par exemple, supposons que les modules modifiés dynamiquement, les packages imbriqués, etc. modules supérieurs de plain-pied).Puis:
>>> 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)>
J'utilise l'ancienne forme ASCII de conserves au vinaigre de sorte que s
, la chaîne contenant le cornichon, est facile à examiner: il demande à unpickling d'appeler la fonction d'importation intégrée, avec le chaîne sys
comme seul argument. Et z
montre que cela nous redonne en effet le module sys
intégré à la suite du désépissage, comme souhaité.
Maintenant, vous devrez rendre les choses un peu plus complexes que simplement __import__
(vous devrez gérer l'enregistrement et la restauration des changements dynamiques, naviguer dans un espace de noms imbriqué, etc.), et ainsi vous devrez aussi appelez copy_reg.constructor
(en passant en argument votre propre fonction qui effectue ce travail) avant la copy_reg
la fonction d'économie de module qui renvoie votre autre fonction (et, si dans une exécution séparée, aussi avant que vous décuplez les pickles que vous avez faites en utilisant ladite fonction). Mais j'espère que ces cas simples aideront à montrer qu'il n'y a vraiment rien de vraiment "compliqué" intrinsèquement! -)
Java Beans .. Python Pickles .. Je voudrais étrangler les nerds qui viennent avec cette cutesy stuff –