Ответ 1
Чтобы ответить на ваш вопрос напрямую: я не вижу никакого вреда в закрытии в конце блока 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 функциональность была добавлена в trunk с помощью этого коммита в 2007 году и, похоже, этот раздел
connections.py
не изменился поскольку. Это объединение на основе этого коммита, которое имеет сообщениеДобавьте поддержку Python-2.5 с инструкцией, описанной в http://docs.python.org/whatsnew/pep-343.html. Пожалуйста, проверьте
И код, который вы цитируете, никогда не изменялся с тех пор.
Это подсказывает мою последнюю мысль - это, вероятно, только первая попытка/прототип, который только что сработал и поэтому никогда не менялся.
Более современная версия
Вы ссылаетесь на источник устаревшей версии соединителя. Я отмечаю, что здесь есть более активный вилок той же библиотеки , на который я ссылаюсь в своих комментариях о "более новой версии" в пункте 1.
Обратите внимание, что в более поздней версии этого модуля реализованы __enter__()
и __exit__()
внутри cursor
: см. здесь. __exit__()
здесь делает вызов self.close()
, и, возможно, это обеспечивает более стандартный способ использования синтаксиса с синтаксисом, например.
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
.