python异常捕获语句_使用Python’with’语句时捕获异常

让我感到羞愧的是,我不知道如何处理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"不起作用,否则:不会引发异常。我该怎么做才能以一种Python般的方式处理"with"语句中的失败呢?

在try/except语句中"enclonding"with"不起作用,否则:不会引发异常"是什么意思?with语句不会神奇地破坏周围的try...except语句。

有趣的是,Java的Test-RealRealSt声明确实支持了你想要的用例。docs.oracle.com/javase/tutorial/essential/exceptions/…

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()

如stackoverflow.com/questions/5205811/…中所述,这里的try块实在太宽了。在创建上下文管理器和WITH语句体中的异常之间没有区别,因此它可能不是所有用例的有效解决方案。

@但是您可以在with中添加额外的try...except块,以更接近与open()无关的异常的来源。

@Rbaleksandar如果我记得正确的话,我的评论严格地引用了答案中的第一个例子,其中整个with语句都在try/except块中(因此,即使您有内部的try/expect块,它们让escape的任何异常仍然会击中外部的块)。道格拉斯随后又增加了第二个例子来处理那些区分重要的案例。

在这个例子中,文件会被关闭吗?我问是因为它是在"with"范围之外打开的。

@MikeCollins退出"with"将关闭打开的文件,即使该文件在"with"之前打开。

利用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

")

我喜欢,但感觉有点太黑魔法了。对读者来说并不完全清楚

@为什么你不定义它,避免每次你需要的时候都这样做?它是在应用程序级别定义的,和任何其他ContextManager一样神奇。我认为使用WITH语句的人会很清楚地理解它(如果您不喜欢它,函数的名称也可能更具表现力)。"with"语句本身就是这样设计的:定义一个"安全"的代码块,并将检查功能委托给上下文管理器(以使代码更清晰)。

所有这些麻烦只是因为没有在用户代码中写入finally块。我开始认为我们都在忍受一个长期的炒作症状。

在Python中处理异常的最佳方法是编写一个函数来捕获并返回异常?真的吗?处理异常的方法是使用try...except语句。

Catching an exception while using a Python 'with' statement

自Python2.6以来,WITH语句在没有__future__导入的情况下可用。您可以早于python 2.5就获得它(但现在是升级的时候了!)用:

from __future__ import with_statement

这是你最需要改正的地方。你快到了,但是with没有except条款:

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

print(f.readlines())

except:                    #

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

采用标准异常处理

try:

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

#business as usual

except Exception as e:

print"oops, handle exception:", e

然后有一天,文件将在os.path.exists检查和打开之间被删除。

很好,现在修好了:)

不,这不是固定的。如果文件在检查和打开调用之间被删除,它仍然可能失败。

@贾斯珀,你开玩笑吧。你能解释更多吗?

别开玩笑了。这个脚本很可能在多线程环境中运行。这意味着它可以在任何时候被中断,其他线程/进程可以做它们的事情。理论上,有可能1)文件存在于检查过程中2)另一个进程中断并碰巧删除了文件3)脚本继续,但没有文件。

在这种情况下,我们需要在打开、更新之前检查它是否存在。

你可能感兴趣的:(python异常捕获语句)