Ich versuche dynamische Objekte zum erneuten Laden in Python zu implementieren, die Codeänderungen live widerspiegeln.Traversieren einer Python-Objektbaumstruktur
Das Neuladen von Modulen funktioniert, aber ich muss jede Instanz der Modulklassen neu erstellen, damit Änderungen wirksam werden.
Das Problem ist, dass Objekte Daten (Objekte Inhalt) während des Prozesses verloren geht.
So habe ich versucht, einen anderen Ansatz:
def refresh(obj, memo=None):
if memo is None:
memo = {}
d = id(obj)
if d in memo:
return
memo[d] = None
try:
obj.__class__ = getattr(sys.modules[obj.__class__.__module__],
obj.__class__.__name__)
except TypeError:
return
for item in obj.__dict__.itervalues():
if isinstance(item, dict):
for k, v in item.iteritems():
refresh(k, memo)
refresh(v, memo)
elif isinstance(item, (list, tuple)):
for v in item:
refresh(v, memo)
else:
refresh(item, memo)
Und überraschenderweise funktioniert es! Nach dem Aufruf von refresh() für meine Objekte wird der neue Code wirksam, ohne dass sie neu erstellt werden müssen.
Aber ich bin mir nicht sicher, ob dies der richtige Weg ist, ein Objekt zu durchlaufen? Gibt es eine bessere Möglichkeit, die Komponenten eines Objekts zu durchlaufen?
Dies ist der von mir verwendeten Lösung sehr ähnlich (einige "Top Level" -Klassen sind umschlossen und verfolgen ihre Instanzen, um sie neu laden zu können). Das Problem besteht darin, dass ich nicht alle Klassen in mein Paket einbinden möchte (oder von einer wieder aufladenden Klasse wie in Ihrem Beispiel erben), sondern nur die obersten. Deshalb brauche ich eine Objektbaum-Traversierungsfunktion. –
Ich glaube, Sie können es nicht mit vollständiger Allgemeinheit tun - abhängig von z.B. __slots__ und andere Metaklassen-Funktionalität, Python-Objekte können so codiert sein, dass sie das einfach nicht unterstützen (deshalb ist eine bestimmte Unterstützung erforderlich, wenn Sie Erweiterungen codieren, für Garbage-Collection-Traversals, schwache Referenzen, Picking/Unpickling, & C). Öffnen Sie Dateien, DB-Verbindungen, Generator-Objekte, Sperren, ... Wenn Sie riskieren, einige Teile zu verpassen, stellen Sie sicher, dass Sie mindestens Sätze, deques, default_factory Mitglieder von defaultdicts usw. usw. –
Ok, dann habe ich einfach um weitere Typprüfungen in meinen Iterationen hinzuzufügen, wechseln Sie. Es wäre schön, irgendeine Art von has_sequence_interface/has_mapping_interface() -Funktionen zu haben, um zu testen, wie ein Objekt iteriert werden kann. –