Abych odpověděl přímo na vaši otázku:nevidím žádnou újmu v uzavření na konci with
blok. Nemohu říci, proč se to v tomto případě nedělá. Ale protože je v této otázce nedostatek aktivity, nechal jsem si prohledat historii kódu a hodím pár myšlenek (hádám ), proč close()
může nesmí se jmenovat:
-
Existuje malá šance, že se točí prostřednictvím volání
nextset()
může vyvolat výjimku - možná to bylo pozorováno a považováno za nežádoucí. To může být důvod, proč novější verzecursors.py
obsahuje tuto strukturu vclose()
: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
-
Existuje (poněkud vzdálený) potenciál, že to může nějakou dobu trvat, než se protočí všechny zbývající výsledky bez nečinnosti. Proto
close()
nemusí být voláno, aby se zabránilo provádění některých zbytečných iterací. Zda si myslíte, že stojí za to ukládat tyto hodinové cykly, je subjektivní, předpokládám, ale můžete argumentovat ve smyslu "pokud to není nutné, nedělejte to". -
Při procházení commitů sourceforge byla funkce přidána do kmene pomocí /a> v roce 2007 a zdá se, že tato část
connections.py
se od té doby nezměnilo. Jedná se o sloučení založené na tomto potvrzení , který má zprávuA kód, který citujete, se od té doby nikdy nezměnil.
To podnítí mou poslední myšlenku - pravděpodobně je to jen první pokus / prototyp, který prostě fungoval, a proto se nikdy nezměnil.
Modernější verze
Odkazujete na zdroj pro starší verzi konektoru. Podotýkám, že existuje aktivnější větev stejné knihovny zde , na který odkazuji ve svých komentářích o "novější verzi" v bodě 1.
Všimněte si, že novější verze tohoto modulu implementovala __enter__()
a __exit__()
v cursor
sám:viz zde
. __exit__()
zde dělá volání self.close()
a možná to poskytuje standardnější způsob použití syntaxe with, např.
with conn.cursor() as c:
#Do your thing with the cursor
Konec poznámek
N.B. Myslím, že bych měl přidat, pokud rozumím shromažďování odpadu (ani nejsem odborník), jakmile nebudou žádné odkazy na conn
, bude přiděleno. V tomto okamžiku nebudou žádné odkazy na objekt kurzoru a bude také uvolněn.
Nicméně volání cursor.close()
neznamená, že se bude sbírat odpad. Jednoduše vypálí výsledky a nastaví připojení na None
. To znamená, že jej nelze znovu použít, ale nebude okamžitě sesbírán. Můžete se o tom přesvědčit ručním voláním cursor.close()
po vašem with
blok a pak, řekněme, tisk nějakého atributu cursor
N.B. 2 Myslím, že toto je poněkud neobvyklé použití with
syntaxe jako conn
objekt přetrvává, protože je již ve vnějším rozsahu - na rozdíl například od běžnějšího with open('filename') as f:
kde nejsou žádné objekty s odkazy za koncem with
blokovat.