e-s*_*tis 40 python exception with-statement
我知道该with声明可以帮助你解决这个问题:
try:
    f = open(my_file)
    do_stuff_that_fails()
except:
    pass
finally:
    f.close()
Run Code Online (Sandbox Code Playgroud)
成:
with open(my_file) as f:
    do_stuff_that_fails()
Run Code Online (Sandbox Code Playgroud)
但那怎么样更好?您仍然需要处理无法打开文件的情况(比如提示用户告诉他他没有权限),所以实际上你有:
try:
    with open(my_file) as f:
        do_stuff_that_fails()
except (IOError, OSError, Failure) as e:
    do_stuff_when_it_doesnt_work()
Run Code Online (Sandbox Code Playgroud)
这相当于:
try:
    f = open(my_file)
    do_stuff_that_fails()
except (IOError, OSError, Faillure) as e:
    do_stuff_when_it_doesnt_work()
finally:
    f.close()
Run Code Online (Sandbox Code Playgroud)
是的,你获得了两行,但是你添加了一个嵌套级别,这使得它更容易阅读.with声明的目的是为了节省两行还是我遗漏了什么?
为此添加一个关键字似乎很多,所以我觉得有一些语法来处理额外的尝试/除了我不知道的.
Tim*_*ney 34
首先,它有助于防止您在try ... finally ...示例中引入的问题.
你已经结构化了,如果尝试打开该文件,那么你将永远不会绑定一个打开的文件的名称抛出一个异常的方式f,导致无论是NameError在在finally条款(如果f从未范围内结合型)或完全的东西意外(如果有).
正确的结构(相当于with)是:
f = open(my_file)
try:
    do_stuff_that_fails()
finally:
    f.close()
Run Code Online (Sandbox Code Playgroud)
(注意 - except如果你没有任何事可做,就不需要一个条款).
你的第二个例子同样是错误的,应该结构如下:
try:
    f = open(my_file)
    try:
        do_stuff_that_fails()
    except EXPECTED_EXCEPTION_TYPES as e:
        do_stuff_when_it_doesnt_work()
    finally:
        f.close()
except (IOError, OSError) as e:
    do_other_stuff_when_it_we_have_file_IO_problems()
Run Code Online (Sandbox Code Playgroud)
第二个是(如另一个答案所述),你不能忘记打电话f.close().
顺便说一句,这个术语是"上下文管理",而不是"资源管理" - with语句管理上下文,其中一些可能是资源,而另一些则不是.例如,它还用于decimal为特定代码块建立小数上下文.
最后(回复你对前一个答案的评论)你不应该依赖refcount语义来处理Python中的资源.Jython,IronPython和PyPy都具有非引用语义,并且没有什么可以防止CPython以其他方式运行(尽管在不久的将来它不太可能).在紧密循环(例如os.walk)中,如果在具有不同行为的VM上运行依赖于refcount语义的代码,则非常容易用完文件句柄.
Mat*_*ner 16
在你给出的例子中,它并不是更好.最好的做法是将异常捕获到接近它们抛出的点,以避免捕获相同类型的无关异常.
try:
    file = open(...)
except OpenErrors...:
    # handle open exceptions
else:
    try:
        # do stuff with file
    finally:
        file.close()
Run Code Online (Sandbox Code Playgroud)
不幸的是,这样做很简单,该with语句不允许您捕获在评估期间抛出的异常.有人建议在邮件列表中添加异常处理:
with open(...) as file:
    # do stuff with file
except OpenErrors...:
    # handle open exceptions
Run Code Online (Sandbox Code Playgroud)
但这被击落了.
最后值得注意的是,您可以直接进入和退出上下文管理器,如下所示:
file = open(...).__enter__()
file.__exit__(typ, val, tb)
Run Code Online (Sandbox Code Playgroud)
作为一般准则,with对于不期望例外的情况,语句表示优异,并且默认的"输入/打开/获取"行为就足够了.示例包括必需文件和简单锁定.
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           30172 次  |  
        
|   最近记录:  |