За да отговоря директно на въпроса ви:не виждам никаква вреда в затварянето в края на with
блок. Не мога да кажа защо не е направено в този случай. Но тъй като има недостиг на активност по този въпрос, направих търсене в историята на кода и ще нахвърля няколко мисли (предположения ) защо close()
може не се нарича:
-
Има малък шанс за въртене чрез извиквания към
nextset()
може да хвърли изключение - вероятно това е било наблюдавано и възприето като нежелателно. Това може да е причината по-новата версия наcursors.py
съдържа тази структура вclose()
: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
-
Има (донякъде отдалечен) потенциал, че може да отнеме известно време, за да превъртите всички останали резултати, без да правите нищо. Следователно
close()
може да не се извиква, за да се избегнат някои ненужни итерации. Предполагам, че смятате, че си струва да запазите тези часовникови цикли, е субективно, но можете да спорите в духа на „ако не е необходимо, не го правете“. -
Преглеждайки ангажиментите на sourceforge, функционалността беше добавена към ствола от този ангажимент през 2007 г. и изглежда, че този раздел на
connections.py
не се е променило оттогава. Това е сливане въз основа на този ангажимент , който съдържа съобщениетоИ кодът, който цитирате, никога не е променян оттогава.
Това подтиква последната ми мисъл - вероятно е само първи опит/прототип, който току-що е проработил и следователно никога не е променян.
По-модерна версия
Свързвате към източника за наследена версия на конектора. Отбелязвам, че има по-активно разклонение на същата библиотека тук , към който давам връзка в коментарите си за „по-нова версия“ в точка 1.
Обърнете внимание, че по-новата версия на този модул е имплементирала __enter__()
и __exit__()
в cursor
себе си:вижте тук
. __exit__()
тук прави извикване на self.close()
и може би това осигурява по-стандартен начин за използване на синтаксиса with, напр.
with conn.cursor() as c:
#Do your thing with the cursor
Крайни бележки
N.B. Предполагам, че трябва да добавя, доколкото разбирам събирането на отпадъци (също не съм експерт), след като няма препратки към conn
, то ще бъде отменено. В този момент няма да има препратки към обекта на курсора и той също ще бъде освободен.
Въпреки това извикване на cursor.close()
не означава, че ще се събира боклук. Той просто записва резултатите и настройва връзката на None
. Това означава, че не може да се използва повторно, но няма да бъде изхвърлен веднага на боклука. Можете да се убедите в това, като извикате ръчно cursor.close()
след вашия with
блок и след това, да речем, отпечатване на някакъв атрибут на cursor
N.B. 2 Мисля, че това е малко необичайно използване на with
синтаксис като conn
обектът продължава, защото вече е във външния обхват - за разлика, да речем, от по-често срещания with open('filename') as f:
където няма обекти, висящи наоколо с препратки след края на with
блокирай.