Wenn ich ein Skript habe, das eine Klasse definiert:
%Vor%und führen Sie dann dieses Skript in seinem eigenen Namespace dict:
aus %Vor%und dann erstellen Sie eine Instanz der Klasse und pickle es:
%Vor%Wenn ich jetzt versuche, es zu entpacken:
%Vor%Ich bekomme den Fehler
%Vor%Ich nehme an, dass das nicht funktioniert, weil Python nicht weiß, wo myClass zu finden ist, um das Objekt neu zu erstellen. Aber meine Klasse existiert im NS-Diktat. Gibt es eine Möglichkeit, Pickle zu sagen, wo die Klasse für das Objekt zu finden ist, das geladen wird?
Ich habe eine Lösung gefunden. Es scheint, als ob das Ausführen von Code in einem Diktat Python daran hindert herauszufinden, wo die Klasse definiert ist. Die Lösung besteht darin, ein leeres Modul zu erstellen, den Code im Modul auszuführen und dann das Modul zu sys.modules hinzuzufügen, damit Python davon erfährt.
%Vor%Jetzt ist es möglich, eine Instanz der Klasse zu pickle und unpickle:
%Vor%Sie können sogar noch einen Schritt weiter gehen und das Objekt sich in den von Ihnen gewünschten Typ rekonstruieren lassen.
%Vor%Die Grundidee ist, dass Sie Ihre Klasse in ein "Trojanisches Pferd" packen, wo ihre Rekonstruktion eine Instanziierung einer anderen Klasse verursacht, als sie ursprünglich war.
Es spielt keine Rolle, was die otherclass
auf der Beizseite enthält. Es kommt nur darauf an, dass es im selben Modulpfad wie die "Ziel" -Klasse existiert - pickle
fügt nur eine String-Repräsentation des Modulnamens in den serialisierten Stream ein.
Also, um zu brechen, was im obigen Code passiert, im Detail:
myClass
. Dies kann über copy_reg
oder die Funktion __reduce_ex__
erfolgen. otherclass
" (was ein Dummy ist. Sie nicht brauchen den "echten" Inhalt von otherclass
auf der Beizseite, weil Alles, was in die Gurke geht, ist der Modul- / Klassenname. otherclass
existiert. otherclass
mit den Daten aus dem Tupel instanziiert, die von der benutzerdefinierten Beizfunktion zurückgegeben werden. Python kann ziemlich mächtig sein!