2009-08-25 7 views
0

Je considère l'utilisation de Quantities pour définir un nombre avec son unité. Cette valeur devra probablement être stockée sur le disque. Comme vous le savez probablement, le décapage a un problème majeur: si vous déplacez le module, unpickling ne sera pas capable de résoudre la classe, et vous ne serez pas en mesure de défaire les informations. Il existe des solutions de contournement pour ce comportement, mais ils sont, en effet, des solutions de contournement.Sérialisation de python stable (par exemple, aucun problème de relocalisation de module de décapage)

Une solution que j'ai fantasmée pour ce problème serait de créer un encodage de chaîne uniquement pour une unité donnée. Une fois que vous avez obtenu ce codage à partir du disque, vous le transmettez à une méthode d'usine dans le module Quantities, qui le décode en une instance d'unité appropriée. L'avantage est que même si vous déplacez le module, tout fonctionnera, à condition de passer le jeton de chaîne magique à la méthode usine.

Est-ce un concept connu?

Répondre

1

On dirait une application du premier principe de Wheeler, "tous les problèmes en informatique peuvent être résolus par un autre niveau d'indirection" (le second principe ajoute "mais cela créera généralement un autre problème" ;-). Essentiellement ce que vous devez faire est une indirection pour identifier le type - entité-dans-type sera très bien avec des approches de décapage (vous pouvez étudier les sources de pickle.py et copy_reg.py pour tous les détails de ce dernier).

Plus précisément, je crois que ce que vous voulez faire est sous-classe pickle.Pickler et remplacer la méthode save_inst. Lorsque la version actuelle dit:

if self.bin: 
     save(cls) 
     for arg in args: 
      save(arg) 
     write(OBJ) 
    else: 
     for arg in args: 
      save(arg) 
     write(INST + cls.__module__ + '\n' + cls.__name__ + '\n') 

vous voulez écrire quelque chose de différent que juste le module de la classe et le nom - une sorte d'identifiant unique (composé de deux cordes) pour la classe, probablement à votre propre registre ou des registres; et de même pour la méthode save_global.

Il est encore plus facile pour votre sous-classe de Unpickler, parce que la partie _instantiate est déjà pris en compte dans sa propre méthode: il vous suffit de passer outre find_class, qui est la suivante:

def find_class(self, module, name): 
    # Subclasses may override this 
    __import__(module) 
    mod = sys.modules[module] 
    klass = getattr(mod, name) 
    return klass 

il faut prendre deux cordes et retour un objet de classe; vous pouvez le faire à travers vos registres, encore une fois.

Comme toujours lorsque des registres sont impliqués, vous devez réfléchir à la façon de vous assurer d'enregistrer tous les objets (classes) d'intérêt, etc., etc. Une stratégie courante est de laisser le décapage seul, mais assurez-vous que tous les mouvements , les renoms de modules, etc, sont enregistrés quelque part de façon permanente; de cette façon, juste le nonpickler sous-classé peut faire tout le travail, et il peut le plus commodément tout faire dans le find_class substitué - en contournant tous les problèmes d'enregistrement. Je suppose que vous considérez cela comme une "solution de contournement" mais pour moi, cela semble être une implémentation extrêmement simple, puissante et pratique du concept "un plus haut niveau d'indirection", qui évite le problème "un problème de plus" ;-)

Questions connexes