2012-03-27 124 views

回答

124

是的,它的行爲與try塊之後的finally塊相同,即它總是執行(除非python進程以不尋常的方式結束)。

它還在的PEP-343一個例子提到的這對with聲明規格:

with locked(myLock): 
    # Code here executes with myLock held. The lock is 
    # guaranteed to be released when the block is left (even 
    # if via return or by an uncaught exception). 

東西值得一提的是,但是,你不能輕易地捕獲由open()調用拋出的異常沒有把整個with塊內try..except塊通常不是人們想要的。

+7

'else'可以添加到'with'來解決'嘗試除了''問題。編輯:添加到語言 – rplnt 2012-03-27 07:51:50

+7

我不知道它是否相關,但就我所知,Process.terminate()是少數(唯一的)場景之一,不保證調用「finally」語句:*「請注意,退出處理程序和最後的子句等將不會執行。」* – 2012-03-27 07:55:37

+0

@RikPoggi [''os._exit'](https://docs.python.org/library/os.html#os。 _exit)有時被使用 - 它退出Python進程而不調用清理處理程序。 – 2016-10-08 06:25:50

18

是的。

def example(path, mode): 
    with open(path, mode) as f: 
     return [line for line in f if condition] 

..是幾乎等同於:

def example(path, mode): 
    f = open(path, mode) 

    try: 
     return [line for line in f if condition] 
    finally: 
     f.close() 

更準確地說,在離開該塊時在上下文管理器的__exit__方法總是被調用(不考慮異常的,則返回等)。文件對象的__exit__方法只是調用f.close()(例如here in CPython

+13

一個有趣的實驗顯示你從'finally' keywrod得到的保證是:'def test():try:return True;最後:返回False'。 – 2014-07-11 19:57:01

4

更一般地,With Statement Context Manager__exit__方法的確會在return的情況下,從上下文中調用。這可以用下面的測試:

class Resource: 
    def __enter__(self): 
     print('Entering context.') 
     return self 

    def __exit__(self, *exc): 
     print('Exiting context.') 

def fun(): 
    with Resource(): 
     print('Returning inside with-statement.') 
     return 
    print('Returning outside with-statement.') 

fun() 

的輸出是:

Entering context. 
Returning inside with-statement. 
Exiting context. 

輸出上述確認__exit__被稱爲儘管return早。因此,上下文管理器不被繞過。

相關問題