Um Ihre Frage direkt zu beantworten:Ich kann überhaupt keinen Schaden darin sehen, am Ende eines with
zu schließen Block. Warum das in diesem Fall nicht gemacht wird, kann ich nicht sagen. Aber da es zu dieser Frage an Aktivität mangelt, habe ich den Codeverlauf durchsucht und werde ein paar Gedanken einwerfen (Vermutungen ) warum das close()
kann nicht aufgerufen werden:
-
Es besteht eine geringe Chance, dass Aufrufe von
nextset()
durchlaufen werden kann eine Ausnahme auslösen - möglicherweise wurde dies beobachtet und als unerwünscht angesehen. Dies könnte der Grund sein, warum die neuere Version voncursors.py
enthält diese Struktur inclose()
:def close(self): """Close the cursor. No further queries will be possible.""" if not self.connection: return self._flush() try: while self.nextset(): pass except: pass self.connection = None
-
Es besteht das (etwas entfernte) Potenzial, dass es einige Zeit dauern könnte, alle verbleibenden Ergebnisse durchzugehen, ohne etwas zu tun. Deshalb
close()
darf nicht aufgerufen werden, um einige unnötige Iterationen zu vermeiden. Ob Sie denken, dass es sich lohnt, diese Taktzyklen zu speichern, ist subjektiv, nehme ich an, aber Sie könnten nach dem Motto "wenn es nicht notwendig ist, tun Sie es nicht" argumentieren. -
Beim Durchsuchen der Sourceforge-Commits wurde die Funktionalität durch dieses Commit
enthältim Jahr 2007 und es scheint, dass dieser Abschnitt von connections.py
hat sich seitdem nicht geändert. Das ist eine Zusammenführung basierend auf diesem Commit , die die NachrichtUnd der von Ihnen zitierte Code hat sich seitdem nie geändert.
Dies veranlasst mich zu meinem letzten Gedanken - es ist wahrscheinlich nur ein erster Versuch / Prototyp, der gerade funktioniert hat und daher nie geändert wurde.
Modernere Version
Sie verlinken auf die Quelle für eine Legacy-Version des Connectors. Ich stelle fest, dass es hier einen aktiveren Fork derselben Bibliothek gibt , auf die ich in meinen Kommentaren zu "neuere Version" in Punkt 1 verlinke.
Beachten Sie, dass die neuere Version dieses Moduls __enter__()
implementiert hat und __exit__()
innerhalb von cursor
selbst:siehe hier
. __exit__()
hier nicht ruft self.close()
und vielleicht bietet dies eine standardisiertere Möglichkeit, die with-Syntax zu verwenden, z. B.
with conn.cursor() as c:
#Do your thing with the cursor
Endnotizen
NB. Ich denke, ich sollte hinzufügen, soweit ich die Garbage Collection verstehe (auch kein Experte), wenn es keine Verweise auf conn
gibt , es wird freigegeben. An diesem Punkt gibt es keine Verweise auf das Cursor-Objekt und es wird auch freigegeben.
Allerdings Aufruf von cursor.close()
bedeutet nicht, dass es Müll gesammelt wird. Es brennt einfach die Ergebnisse durch und setzt die Verbindung auf None
. Dies bedeutet, dass es nicht wiederverwendet werden kann, aber es wird nicht sofort der Müllabfuhr zugeführt. Davon können Sie sich selbst überzeugen, indem Sie cursor.close()
manuell aufrufen nach Ihrem with
Block und dann, sagen wir, ein Attribut von cursor
ausgeben
Hinweis:2 Ich denke, das ist eine etwas ungewöhnliche Verwendung von with
Syntax als conn
Das Objekt bleibt bestehen, weil es sich bereits im äußeren Gültigkeitsbereich befindet – im Gegensatz zu beispielsweise dem häufigeren with open('filename') as f:
wo keine Objekte mit Verweisen nach dem Ende von with
herumhängen blockieren.