Ich habe ein eigenartiges Python-Problem. Während der Ausführung meiner gtk-Python-Anwendung verlieren einige meiner Klassenobjekte auf mysteriöse Weise Attribute, wodurch einige Funktionen meines Programms unterbrochen werden.
Es ist schwer zu sagen, warum dies passieren könnte - ich lösche nie absichtlich Attribute, und die fraglichen Klassen erben von einer Klasse, die ich selbst geschrieben habe (und keine anderen).
Ich kann das Problem auslösen, indem ich eine bestimmte Aktion wiederhole (zum Beispiel viele Aufrufe der Methode add_card
- entweder durch Klicken oder Öffnen einer Datei, wodurch add_card
etwa zwanzigmal aufgerufen wird)
Ich bin wirklich ratlos, und ich wünschte, ich hätte mehr Informationen, die ich für nützlich halten könnte.
Was kann dazu führen, dass ein Python-Objekt Attribute verliert?
BEARBEITEN, Re. Fragen:
Hier sind Beispieltracebacks in Bezug auf die zwei Attribute, die ich verliere:
%Vor%Und hier ist, wo sie eingestellt sind:
%Vor% Diese spezielle Unterklasse nennt sie nicht die Oberklasse __init__
, so dass die Attributsätze in der Unterklasse dupliziert sind:
Alle anderen Unterklassen von DeckerGenericList haben dasselbe Problem und sie sind alle wie folgt definiert:
%Vor%PyQT (und daher vielleicht auch PyGtk oder ein anderes Framework) hat das seltsame Verhalten, dass ein Attributfehler irgendwo innerhalb / unterhalb des Attributcodes tatsächlich dazu führt, dass Python meldet, dass das aufgerufene Attribut für dieses Objekt nicht existiert.
Es gibt irgendwo eine (etwas offizielle) Geschichte darüber, warum das so ist (und ist eigentlich richtiges und verständliches Verhalten). Es hat etwas mit __getattr_ zu tun, das auf einer Basisklasse definiert ist: Der Mechanismus, nach dem das funktioniert, ist, dass, wenn der Aufruf eines Attributs auf ein Attribut zu einem Attributfehler führt, die Methode __getattr__ aufgerufen wird. Aber diese Methode hat keine Ahnung, was "Attribut" eigentlich nicht gefunden wurde. Und da das (PyQt.QObject) __getattr__ entworfen wurde, um "spezifische" Attribute zu implementieren, beschließt es, einen weiteren AttributeError auszulösen, der das Attribut "called" erwähnt.
Wie auch immer, es könnte sein, dass Sie von einem Objekt erben, das __getattr__ irgendwo verwendet und dass Ihr eigener Attributcode (ein anderes) Attribut aufruft, das tatsächlich nicht existiert. Was Sie tun können, um dies zu überprüfen, ist:
%Vor%Update / Hinweis: Auch wenn Sie __getattr__ selbst auf Ihrem DeckerGenericList-Objekt implementieren, seien Sie aus demselben Grund vorsichtig damit! Wenn man AttributeErrors innerhalb von __getattr__ anruft, führt das meistens zu einem merkwürdigen Verhalten wie diesem. Beachten Sie, dass es keine einfache Lösung gibt: Der 'echte' AttributeError trägt nur eine String-Nachricht (und nicht spezifisch den tatsächlichen Attributnamen), aber viel wichtiger: Die __getattr_-Funktion sieht den ursprünglichen AttributeError nie an erster Stelle.
Ich denke, es ist ein Garbage-Collector-Bug. Ich hatte ein ähnliches Problem und ich denke, ich habe es auf den GC beschränkt.
Fügen Sie am Anfang des Moduls eine Liste extra_references = []
hinzu, die die Klasse enthält, die Attribute verliert. Fügen Sie in der Methode __init__
für die Klasse den folgenden Code hinzu:
Dadurch wird sichergestellt, dass immer ein Verweis auf das Objekt außerhalb von GObject vorhanden ist.
Wenn das Problem verschwindet, frisst Pythons Garbage Collector dein Objekt auf, bevor du damit fertig bist. Riecht sehr nach diesem Fehler (der angeblich behoben wurde): Ссылка