当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《使用Python'with'语句时捕获异常》经验,为你挑选了3个好方法。

令我遗憾的是,我无法弄清楚如何处理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'语句内部的失败,我该怎么办?



1> Douglas Leed..:
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()


@MikeCollins退出“ with”将关闭打开的文件,即使该文件在“ with”之前打开。
如http://stackoverflow.com/questions/5205811/catching-an-exception-while-using-a-python-with-statement-part-2中所述,此处的try块实际上太宽泛了.创建上下文管理器时的异常与with语句的主体中的异常没有区别,因此它可能不是所有用例的有效解决方案.
在此示例中,文件会关闭吗?我问是因为它是在“ with”范围之外打开的。

2> 小智..:

使用该with语句的最佳"Pythonic"方法在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")


我喜欢它,但感觉有点太黑魔法了.它对读者来说并不完全明确
所有这些麻烦只是因为没有在用户代码中写finally块.我开始认为我们都因为声明中的长期炒作症状而受苦.
@PaulSeeb为什么你不定义它并且每次你需要时都不会这样做?它是在您的应用程序级别定义的,它与任何其他上下文管理器一样神奇.我认为使用with语句的人会清楚地理解它(如果你不喜欢它,函数的名称也可能更具表现力)."with"语句本身已设计为以这种方式工作,以定义"安全"代码块并将检查函数委托给上下文管理器(以使代码更清晰).

3> Aaron Hall..:

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

自Python 2.6以来,with语句一直没有__future__导入.您可以早在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,except块:

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

推荐阅读
围脖上的博博_771
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有