Om je vraag direct te beantwoorden:ik zie geen enkel kwaad in het afsluiten aan het einde van een with
blok. Ik kan niet zeggen waarom het in dit geval niet wordt gedaan. Maar aangezien er een gebrek aan activiteit is met betrekking tot deze vraag, heb ik de codegeschiedenis doorzocht en zal ik een paar gedachten opwerpen (gissingen ) over waarom de close()
mag niet gebeld worden:
-
Er is een kleine kans dat aanroepen naar
nextset()
kan een uitzondering veroorzaken - mogelijk was dit waargenomen en als ongewenst beschouwd. Dit is misschien de reden waarom de nieuwere versie vancursors.py
bevat deze structuur 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
-
Er is het (enigszins afgelegen) potentieel dat het enige tijd kan duren om alle resterende resultaten te doorlopen terwijl u niets doet. Daarom
close()
mag niet worden aangeroepen om te voorkomen dat u onnodige iteraties uitvoert. Of je denkt dat het de moeite waard is om die klokcycli te bewaren, is subjectief, denk ik, maar je zou kunnen redeneren in de trant van "als het niet nodig is, doe het dan niet". -
Door de sourceforge-commits te bladeren, is de functionaliteit aan de trunk toegevoegd door deze commit in 2007 en het lijkt erop dat dit gedeelte van
connections.py
is sindsdien niet veranderd. Dat is een merge gebaseerd op deze commit , met de boodschapEn de code die je citeert is sindsdien nooit meer veranderd.
Dit roept mijn laatste gedachte op - het is waarschijnlijk slechts een eerste poging / prototype dat net werkte en daarom nooit is veranderd.
Moderne versie
U linkt naar de bron voor een oudere versie van de connector. Ik merk op dat er een actievere fork is van dezelfde bibliotheek hier , waarnaar ik link in mijn opmerkingen over "nieuwere versie" in punt 1.
Merk op dat de recentere versie van deze module __enter__()
. heeft geïmplementeerd en __exit__()
binnen cursor
zelf:zie hier
. __exit__()
hier doet bel self.close()
en misschien biedt dit een meer standaard manier om de syntaxis te gebruiken, bijvoorbeeld
with conn.cursor() as c:
#Do your thing with the cursor
Eindnoten
NB Ik denk dat ik moet toevoegen, voor zover ik het verzamelen van afval begrijp (ook geen expert) zodra er geen verwijzingen zijn naar conn
, zal de toewijzing worden opgeheven. Op dit punt zijn er geen verwijzingen naar het cursorobject en wordt de toewijzing ook ongedaan gemaakt.
Echter aanroepen van cursor.close()
betekent niet dat het afval wordt opgehaald. Het brandt gewoon de resultaten door en zet de verbinding op None
. Dit betekent dat het niet opnieuw kan worden gebruikt, maar het zal niet meteen worden ingezameld. U kunt uzelf daarvan overtuigen door handmatig cursor.close()
. aan te roepen na je with
blokkeren en dan, laten we zeggen, een attribuut van cursor
afdrukken
NB 2 Ik denk dat dit een ietwat ongebruikelijk gebruik is van de with
syntaxis als de conn
object blijft bestaan omdat het zich al in de buitenste scope bevindt - in tegenstelling tot bijvoorbeeld de meer gebruikelijke with open('filename') as f:
waar er geen objecten rondhangen met verwijzingen na het einde van de with
blok.