Следует ли мне позвонить close() после urllib.urlopen()?

Я новичок в Python и читаю код другого:

должен urllib.urlopen() следовать urllib.close()? В противном случае можно было бы утекнуть соединения, исправить?

Ответ 1

Метод close должен быть вызван на результат urllib.urlopen, не в самом модуле urllib, о чем вы думаете (как вы упомянули urllib.close), который не существует).

Лучший подход: вместо x = urllib.urlopen(u) и т.д. используйте:

import contextlib

with contextlib.closing(urllib.urlopen(u)) as x:
   ...use x at will here...

Оператор with и менеджер контекста closing обеспечат правильное закрытие даже при наличии исключений.

Ответ 2

Как и @Peter, открытые URL-адреса вне сферы видимости станут подходящими для сбора мусора.

Однако также обратите внимание, что urllib.py определяет:

 def __del__(self):
        self.close()

Это означает, что , когда счетчик ссылок для этого экземпляра достигнет нуля, его метод __del__ будет вызван, и поэтому его метод close также будет вызываться. Самый "нормальный" способ подсчета ссылок достигнуть нуля - это просто позволить экземпляру выйти из области видимости, но там ничего строго не останавливает вас от явного del x раньше (однако он не вызывает непосредственно __del__, а просто уменьшает количество ссылок на единицу).

Конечно, хороший стиль для явного закрытия ваших ресурсов - особенно когда ваше приложение рискует использовать слишком много указанных ресурсов, но Python автоматически очистит вас, если вы не сделаете ничего смешного, как поддержание (круговое?) ссылки на примеры, которые вам больше не нужны.

Ответ 3

Строго говоря, это верно. Но на практике один раз (если) urllib выходит за пределы области действия, соединение будет закрыто автоматическим сборщиком мусора.