Je crée des types d'objets de manière dynamique en utilisant la fonction de type. EX
return type('DynamicType', (object,), dict)
7 Réponses :
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. P>
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
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): P>
"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. (...) " p>
Afaik, le module JSON exige que vous sachiez le type d'objet avant la main et le dire explicitement quoi faire avec ce type.
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) P>
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
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. P>
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é p>
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
Vous devez également l'injecter avant de décompresser, il est donc inutile.
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)
Quel paramètre CLS CODE> 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.
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. P>