Pour répondre directement à votre question :je ne vois aucun mal à conclure à la fin d'un with
bloquer. Je ne peux pas dire pourquoi ce n'est pas fait dans ce cas. Mais, comme il y a peu d'activité sur cette question, j'ai effectué une recherche dans l'historique du code et j'y ajouterai quelques réflexions (suppositions ) pourquoi le close()
peut ne pas être appelé :
-
Il y a une petite chance que les appels à
nextset()
tournent peut lancer une exception - cela a peut-être été observé et considéré comme indésirable. C'est peut-être pourquoi la nouvelle version decursors.py
contient cette structure dansclose()
: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
-
Il y a le potentiel (quelque peu éloigné) que cela puisse prendre un certain temps pour parcourir tous les résultats restants sans rien faire. Donc
close()
ne peut pas être appelé pour éviter de faire des itérations inutiles. Que vous pensiez que cela vaut la peine d'économiser ces cycles d'horloge est subjectif, je suppose, mais vous pourriez argumenter dans le sens de "si ce n'est pas nécessaire, ne le faites pas". -
En parcourant les commits de sourceforge, la fonctionnalité a été ajoutée au tronc par ce commit en 2007 et il semble que cette section de
connections.py
n'a pas changé depuis. C'est une fusion basée sur ce commit , qui contient le messageEt le code que vous citez n'a jamais changé depuis.
Cela incite ma dernière réflexion - c'est probablement juste une première tentative / un prototype qui vient de fonctionner et qui n'a donc jamais été modifié.
Version plus moderne
Vous créez un lien vers la source d'une version héritée du connecteur. Je note qu'il existe un fork plus actif de la même bibliothèque ici , auquel je renvoie dans mes commentaires sur la "nouvelle version" au point 1.
Notez que la version la plus récente de ce module a implémenté __enter__()
et __exit__()
dans cursor
lui-même :voir ici
. __exit__()
ici fait appelez self.close()
et peut-être que cela fournit un moyen plus standard d'utiliser la syntaxe with, par exemple
with conn.cursor() as c:
#Do your thing with the cursor
Notes de fin
N. B. Je suppose que je devrais ajouter, pour autant que je comprenne la collecte des ordures (pas un expert non plus) une fois qu'il n'y a aucune référence à conn
, il sera désaffecté. À ce stade, il n'y aura aucune référence à l'objet curseur et il sera également désalloué.
Cependant appelant cursor.close()
ne signifie pas qu'il sera ramassé. Il brûle simplement les résultats et définit la connexion sur None
. Cela signifie qu'il ne peut pas être réutilisé, mais il ne sera pas ramassé immédiatement. Vous pouvez vous en convaincre en appelant manuellement cursor.close()
après votre with
bloquer puis, disons, imprimer un attribut de cursor
N. B. 2 Je pense que c'est une utilisation quelque peu inhabituelle du with
syntaxe comme conn
l'objet persiste car il est déjà dans la portée externe - contrairement, par exemple, au with open('filename') as f:
où il n'y a pas d'objets suspendus avec des références après la fin du with
bloquer.