Aby odpowiedzieć bezpośrednio na twoje pytanie:nie widzę żadnej szkody w zamykaniu na końcu with
blok. Nie potrafię powiedzieć, dlaczego nie robi się tego w tym przypadku. Jednak ze względu na brak aktywności w tej kwestii, przeszukałem historię kodu i wrzucę kilka przemyśleń (domysłów ) o tym, dlaczego close()
może nie nazywać się:
-
Istnieje niewielka szansa, że przejdziemy przez wywołania
nextset()
może zgłosić wyjątek — prawdopodobnie został on zaobserwowany i uznany za niepożądany. Może dlatego nowsza wersjacursors.py
zawiera tę strukturę wclose()
: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
-
Istnieje (nieco odległy) potencjał, że może zająć trochę czasu, aby przejść przez wszystkie pozostałe wyniki, nie robiąc nic. Dlatego
close()
nie może zostać wywołany, aby uniknąć niepotrzebnych iteracji. Przypuszczam, że to, czy uważasz, że warto oszczędzać te cykle zegara, jest subiektywne, ale możesz argumentować w stylu „jeśli nie jest to konieczne, nie rób tego”. -
Przeglądając zatwierdzenia Sourceforge, funkcjonalność została dodana do bagażnika przez to zatwierdzenie w 2007 roku i wygląda na to, że ta sekcja
connections.py
nie zmienił się od tego czasu. To scalanie oparte na tym zatwierdzeniu , który zawiera komunikatA cytowany przez Ciebie kod nigdy się nie zmienił.
To skłania do mojej ostatniej myśli - to prawdopodobnie tylko pierwsza próba / prototyp, który po prostu działał i dlatego nigdy się nie zmienił.
Bardziej nowoczesna wersja
Łączysz ze źródłem starszej wersji oprogramowania sprzęgającego. Zauważam, że istnieje bardziej aktywny widelec tej samej biblioteki tutaj , do którego odsyłam w komentarzach na temat „nowszej wersji” w punkcie 1.
Zauważ, że w nowszej wersji tego modułu zaimplementowano __enter__()
i __exit__()
wewnątrz cursor
sam:zobacz tutaj
. __exit__()
tutaj robi wywołaj self.close()
i być może zapewnia to bardziej standardowy sposób używania składni ze składnią, np.
with conn.cursor() as c:
#Do your thing with the cursor
Uwagi końcowe
Uwaga Myślę, że powinienem dodać, o ile rozumiem odśmiecanie (też nie ekspert), gdy nie ma odniesień do conn
, zostanie cofnięty alokacja. W tym momencie nie będzie żadnych odniesień do obiektu kursora i zostanie on również cofnięty.
Jednak wywołanie cursor.close()
nie oznacza, że będą zbierane śmieci. Po prostu sprawdza wyniki i ustawia połączenie na None
. Oznacza to, że nie można ich ponownie użyć, ale nie zostaną one natychmiast zebrane. Możesz się o tym przekonać, ręcznie wywołując cursor.close()
po twoim with
blokuje, a następnie, powiedzmy, wypisuje jakiś atrybut cursor
Uwaga 2 Myślę, że jest to nieco nietypowe użycie with
składnia jako conn
obiekt utrzymuje się, ponieważ znajduje się już w zewnętrznym zakresie - w przeciwieństwie, powiedzmy, bardziej powszechnego with open('filename') as f:
gdzie nie ma żadnych obiektów wiszących z referencjami po zakończeniu with
blokować.