7
votes

Python: économisez des types d'objet créés dynamiquement

Je crée des types d'objets de manière dynamique en utilisant la fonction de type. EX

return type('DynamicType', (object,), dict)


0 commentaires

7 Réponses :


0
votes

en Python, les classes sont des objets aussi. Ainsi, vous devriez être capable de corroger les objets de classe et de les enregistrer dans un fichier. Vous pouvez ensuite les pickler plus tard.


1 commentaires

Vous répondez ne fonctionne pas pour des types créés de manière dynamique. J'essaie de créer des formulaires dynamiques django et d'obtenir cette erreur lorsque j'essaie de sauvegarder le formulaire ne peut pas corner : ce n'est pas trouvé comme Django.Forms .Forms.Dynamicform



0
votes

Peut-être que vous pourriez essayer le module JSON (note: je ne l'ai pas utilisé moi-même, je ne sais pas si cela résoudra votre problème, c'est juste une suggestion):

"Le module JSON fournit une API similaire au cornichon pour convertir des objets Python en mémoire en une représentation sérialisée appelée notation d'objet JavaScript (JSON). Contrairement à Pickle, JSON bénéficie de la mise en œuvre dans de nombreuses langues (en particulier JavaScript). , ce qui est approprié pour la communication inter-applications. JSON est probablement le plus largement utilisé pour communiquer entre le serveur Web et le client dans une application Ajax, mais ne se limite pas à ce domaine problématique. (...) "

module JSON au "module Python de la semaine" Site Web


1 commentaires

Afaik, le module JSON exige que vous sachiez le type d'objet avant la main et le dire explicitement quoi faire avec ce type.



3
votes

Vous ne pouvez pas rechercher des cours, même si vous résolvez votre "... non trouvé comme ..." Problème, cela ne fonctionnera toujours pas (comme dans Enregistrer le nom de la classe, sans le contenu, puis ne pas écrire Défliquez car la classe n'existe pas après le redémarrage de votre programme)

Vous devrez sérialiser manuellement la dicte et reconstruire la classe de la classe plus tard, qui dépend de ce qu'il contient sera aussi amusant: les objets de fonction ne peuvent être sérialisés par rien, vous devez extraire leurs objets de code, les sérialiser avec maréchal puis les recréer lors du chargement.


0 commentaires

0
votes

Sauvegarder la dicte à JSON semble être la plus facile, mais il semble que le cornichon ou une étagère puisse être exploité pour créer une sorte de sérialisation dynamique de classe.

Une recherche rapide sur So révèle ce post utile: Obtenir le chemin de la classe ou le nom de la classe d'une classe en python, même s'il est imbriqué


0 commentaires

0
votes

Vous pouvez "injecter" la nouvelle classe dans l'espace de noms global avant de décaper pour éviter l'erreur de cornichon:

import pickle

class TestClass(object):
    def __init__(self):
        self.a = 1     # Initial instance attributes
        self.b = 2
        self.c = 3

my_classname = "NewTestClass"
obj = type(my_classname, (TestClass,), {})()
obj.d = 4                # Extra attributes
print obj.a, obj.b, obj.c, obj.d
print obj.__class__

globals()[my_classname] = obj.__class__     # Inject the new class in the global namespace

obj2 = pickle.dumps(obj)
obj = None           # Free original obj instance
obj = pickle.loads(obj2)
print obj.a, obj.b, obj.c, obj.d   # 1,2,3,4


1 commentaires

Vous devez également l'injecter avant de décompresser, il est donc inutile.



3
votes

Que diriez-vous de créer une classe d'usine avec des méthodes pour créer, cornichons et pickler des objets de type créé de manière dynamique? Ce qui suit est un début approximatif. Pour utiliser, remplacez simplement les appels en pickle.dump (type, fh) avec typeFactory.pickle (Type, FH) et remplacez les appels sur Pickle.load (FH) avec typeFactory.unpickle (FH).

import pickle

class TypeFactory(object):
    def __init__(self):
        pass
    @staticmethod
    def create_type(name='DynamicType', dict={}):
        return type(name, (object,), dict)
    @staticmethod
    def pickle(t, fh):
        dict = t.__dict__.copy()
        name = t.__name__
        for key in dict.keys():
            if key.startswith('__') and key.endswith('__'):
                del dict[key]
        pickle.dump((name, dict), fh)
    @classmethod
    def unpickle(cls, fh):
        name, dict = pickle.load(fh)
        return cls.create_type(name, dict)


2 commentaires

Quel paramètre CLS devrais-je passer à décompresser, car il est improbable que je connaisse la définition de la classe marinée au préalable.


Le désactivation peut être fait avec typeFactory.Unpickle (FH), où les CLS sont implicitement fournis à la méthode de pickle () car il est défini comme un @ClassMethod. Ajouté ce détail à la réponse maintenant.



0
votes

Il n'y a pas de solution automatique pour votre question. Tous les mécanismes "par défaut", tels que cornichons, enregistrent simplement les données d'instance (y compris les métadonnées comme le type). Ce que vous voulez faire, c'est aussi sauver la classe. Vous pourrez peut-être construire quelque chose en utilisant la magie du code octet, mais il est probablement plus facile de mettre en œuvre votre propre code de sérialisation.


0 commentaires