使用Python'with'语句时捕获异常

问题描述 投票:238回答:4

令我遗憾的是,我无法弄清楚如何处理python'with'语句的异常。如果我有一个代码:

with open("a.txt") as f:
    print f.readlines()

我真的想要处理'文件未找到异常'以便做某事。但我不能写

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语句中包含'with'不起作用:不引发异常。为了以Pythonic方式处理'with'语句内部的失败,我该怎么办?

python exception-handling
4个回答
221
投票
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()

63
投票

最好的“Pythonic”方法,利用with语句,在PEP 343中列为示例#6,它给出了语句的背景。

@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")

49
投票

使用Python'with'语句时捕获异常

在没有__future__ import since Python 2.6的情况下可以使用with语句。您可以将它作为early as 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 builtin的__exit__不返回True,所以你需要在try中嵌套它,除了块:

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

-3
投票

诉诸于标准的异常处理

try:
    with open("a.txt") as f:
        #business as usual
except Exception as e:
    print "oops, handle exception: ", e
© www.soinside.com 2019 - 2024. All rights reserved.