Захват исключения при использовании инструкции Python с '
К моему стыду, я не могу понять, как обрабатывать исключение для выражения python 'with'. Если у меня есть код:
with open("a.txt") as f:
print f.readlines()
Я действительно хочу обработать "не найденное исключение", чтобы сделать somehing. Но я не могу написать
with open("a.txt") as f:
print f.readlines()
except:
print 'oops'
и не может писать
with open("a.txt") as f:
print f.readlines()
else:
print 'oops'
вложение 'с' в оператор try/except не работает иначе: исключение не возникает. Что я могу сделать, чтобы обработать сбой внутри "с помощью" в Pythonic?
Ответы
Ответ 1
from __future__ import with_statement
try:
with open( "a.txt" ) as f :
print f.readlines()
except EnvironmentError: # parent of IOError, OSError *and* WindowsError where available
print 'oops'
Если вы хотите различную обработку ошибок от открытого вызова против рабочего кода, который вы могли бы сделать:
try:
f = open('foo.txt')
except IOError:
print('error')
else:
with f:
print f.readlines()
Ответ 2
Лучший способ "Pythonic" для этого, используя оператор with
, указан в примере № 6 в PEP 343, который дает фон утверждение.
@contextmanager
def opened_w_error(filename, mode="r"):
try:
f = open(filename, mode)
except IOError, err:
yield None, err
else:
try:
yield f, None
finally:
f.close()
Используется следующим образом:
with opened_w_error("/etc/passwd", "a") as (f, err):
if err:
print "IOError:", err
else:
f.write("guido::0:0::/:/bin/sh\n")
Ответ 3
Поймать исключение при использовании Python с оператором
Оператор with был доступен без импорта __future__
начиная с Python 2.6. Вы можете получить его уже в Python 2.5 (но сейчас самое время его обновить!) С помощью:
from __future__ import with_statement
Здесь самое близкое исправление, которое у вас есть. Вы почти у цели, но with
предложением except
:
with open("a.txt") as f:
print(f.readlines())
except: # <- with doesn't have an except clause.
print('oops')
Метод __exit__
диспетчера контекста, если он возвращает False
, по окончании выдает ошибку. Если он возвращает True
, он его подавляет. open
встроенная __exit__
не возвращает True
, поэтому вам просто нужно вложить ее в попытку, кроме блока:
try:
with open("a.txt") as f:
print(f.readlines())
except Exception as error:
print('oops')
И стандартный шаблон: не используйте голые, except:
который ловит BaseException
и все другие возможные исключения и предупреждения. Будьте как минимум так же конкретны, как Exception
, и для этой ошибки, возможно, перехватите IOError
. Только ловить ошибки, которые вы готовы обрабатывать.
Так что в этом случае вы бы сделали:
>>> try:
... with open("a.txt") as f:
... print(f.readlines())
... except IOError as error:
... print('oops')
...
oops
Ответ 4
прибегнуть к стандартной обработке исключений
try:
with open("a.txt") as f:
#business as usual
except Exception as e:
print "oops, handle exception: ", e