Es löscht einfach den lokalen Bezug auf self
, um sicherzustellen, dass, wenn eine Ausnahme die Referenz auftritt übergeben an self._loop.call_exception_handler()
ist die einzige verbleibende Referenz und kein Zyklus wurde erstellt.
Dies wird hier immer noch benötigt, da der lokale Namespace durch die Ausnahme-Traceback referenziert wird; Es wird nicht gelöscht werden, wenn die Funktion verlässt, da es einen Verweis auf die Einheimischen immer noch gibt. Diese
ist dokumentiert im sys.exc_info()
function documentation mit einer Warnung:
Warnung: Zuweisen der Zurückverfolgungs Rückgabewert auf eine lokale Variable in einer Funktion, die eine Ausnahme ist der Umgang wird eine kreisförmige Referenz verursachen. Dadurch wird verhindert, dass alles, auf das von einer lokalen Variablen in der gleichen Funktion oder vom Traceback verwiesen wird, als Garbage Collection behandelt wird. Da die meisten Funktionen keinen Zugriff auf das Traceback benötigen, ist die beste Lösung, etwas wie exctype, value = sys.exc_info()[:2]
zu verwenden, um nur den Ausnahmetyp und -wert zu extrahieren. Wenn Sie die Rückverfolgung benötigen, müssen Sie sie nach der Verwendung löschen (am besten mit einer try ... finally
-Anweisung) oder in einer Funktion aufrufen, die selbst keine Ausnahme behandelt.
Da tulip
Handler eine grundlegenden Rahmen Klasse bildet der Code die Zurückverfolgungskreisreferenzgriffe durch self
aus dem lokalen Namespace statt zu entfernen, da es nicht garantieren kann, dass die _callback
oder call_exception_handler
Funktionen werden ihre Referenzen aufklären.
In CPython werden Objekte zerstört, wenn ihre Referenzzahl auf 0 fällt, aber eine zyklische Referenz (eine Reihe von Objekten, die sich selbst in einem Zyklus referenzieren) wird nie ihre Referenzzahl auf 0 fallen lassen. Der Garbage Collector versucht zu brechen Solche Zyklen können aber nicht immer schnell genug sein. Das explizite Löschen von Referenzen vermeidet das Erstellen von Zyklen.
Zum Beispiel, wenn es eine __del__
Methode gibt, bricht der Garbage Collector keinen Zyklus ab, da er nicht weiß, in welcher Reihenfolge ein Zyklus in diesem Fall sicher unterbrochen wird.
Auch wenn es keine __del__
Methode gibt (die eine Framework-Klasse niemals annehmen sollte, ist dies nicht der Fall), ist es am besten, sich nicht auf den Garbage Collector zu verlassen, der die Zyklen schließlich löscht.
Vielleicht sollte die Frage sein "warum kann die Einstellung" self "auf" None "Zyklen brechen? Welche Zyklen?" – satoru