закрытие файлов, правильно открываемых с помощью urllib2.urlopen ()

У меня есть код в сценарии python

try: # send the query request sf = urllib2.urlopen(search_query) search_soup = BeautifulSoup.BeautifulStoneSoup(sf.read()) sf.close() except Exception, err: print("Couldn't get programme information.") print(str(err)) return 

Я обеспокоен тем, что если я столкнулся с ошибкой в sf.read() , то sf.clsoe() не вызывается. Я попытался поместить sf.close() в блок finally , но если в urlopen() есть исключение, нет файла для закрытия, и я получаю исключение в блоке finally !

Итак, я попробовал

  try: with urllib2.urlopen(search_query) as sf: search_soup = BeautifulSoup.BeautifulStoneSoup(sf.read()) except Exception, err: print("Couldn't get programme information.") print(str(err)) return 

но это привело к недопустимой синтаксической ошибке в строке with... Как я могу лучше справиться с этим, я чувствую себя глупо!

Как отмечают комментаторы, я использую Pys60, который является python 2.5.4

8 Solutions collect form web for “закрытие файлов, правильно открываемых с помощью urllib2.urlopen ()”

Почему бы просто не попробовать закрыть sf и пропустить, если он не существует?

 import urllib2 try: search_query = 'http://blah' sf = urllib2.urlopen(search_query) search_soup = BeautifulSoup.BeautifulStoneSoup(sf.read()) except urllib2.URLError, err: print(err.reason) finally: try: sf.close() except NameError: pass 

Я бы использовал contextlib.closing (в сочетании с __future__ import with_statement для старых версий Python):

 from contextlib import closing with closing(urllib2.urlopen('http://blah')) as sf: search_soup = BeautifulSoup.BeautifulStoneSoup(sf.read()) 

Или, если вы хотите избежать утверждения with:

 try: sf = None sf = urllib2.urlopen('http://blah') search_soup = BeautifulSoup.BeautifulStoneSoup(sf.read()) finally: if sf: sf.close() 

Не совсем так элегантно.

 finally: if sf: sf.close() 

Учитывая, что вы пытаетесь использовать «с», вы должны быть на Python 2.5, а затем это тоже относится: http://docs.python.org/tutorial/errors.html#defining-clean-up -actions

Похоже, проблема идет глубже, чем я думал – этот поток форума указывает, что urllib2 не реализуется до тех пор, пока не будет python 2.6, и, возможно, не до 3.1

Вы можете создать свой собственный универсальный открыватель URL:

 from contextlib import contextmanager @contextmanager def urlopener(inURL): """Open a URL and yield the fileHandle then close the connection when leaving the 'with' clause.""" fileHandle = urllib2.urlopen(inURL) try: yield fileHandle finally: fileHandle.close() 

Затем вы можете использовать свой синтаксис из исходного вопроса:

 with urlopener(theURL) as sf: search_soup = BeautifulSoup.BeautifulSoup(sf.read()) 

Это решение дает вам четкое разделение проблем. Вы получаете чистый общий синтаксис urlopener, который обрабатывает сложности правильного закрытия ресурса, независимо от ошибок, которые возникают под вашим предложением.

Почему бы просто не использовать несколько блоков try / except?

 try: # send the query request sf = urllib2.urlopen(search_query) except urllib2.URLError as url_error: sys.stderr.write("Error requesting url: %s\n" % (search_query,)) raise try: search_soup = BeautifulSoup.BeautifulStoneSoup(sf.read()) except Exception, err: # Maybe catch more specific Exceptions here sys.stderr.write("Couldn't get programme information from url: %s\n" % (search_query,)) raise # or return as in your original code finally: sf.close() 

Если urlopen () имеет исключение, поймайте его и вызовите функцию close () исключения следующим образом:

 try: req = urllib2.urlopen(url) req.close() print 'request {0} ok'.format(url) except urllib2.HTTPError, e: e.close() print 'request {0} failed, http code: {1}'.format(url, e.code) except urllib2.URLError, e: e.close() print 'request {0} error, error reason: {1}'.format(url, e.reason) 

исключение также является полным объектом ответа, вы можете увидеть это сообщение об ошибке : http://bugs.jython.org/issue1544

  • Добавить файл SSL CA с помощью urllib2
  • Как отправить настраиваемый заголовок с urllib2 в HTTP-запросе?
  • Запрос python api не выводит данные внутри тел таблицы
  • Основная выборка HTML-объекта URL с Python 3.x
  • И использование файлов cookie и прокси в Python с urllib2
  • Устранение сбоев "ssl certificate verify failed" ошибка
  • Загрузите файл с помощью urllib в Python с помощью функции wget -c
  • Python обрабатывает имя пользователя и пароль для URL-адреса
  • Python - лучший язык программирования в мире.