2012-03-27 11 views

答えて

124

はい、tryブロックの後にfinallyブロックのように動作します。つまり、常に実行されます(ただし、Pythonプロセスが異常な方法で終了しない限り)。

またwith文の仕様ですPEP-343の例の一つで言及されています言及する価値

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ブロックがあります。

+7

「try with except」問題を解決するために 'else'を' with'に追加することができます。編集:言語に追加されました – rplnt

+7

私が知っている限り、 'Process.terminate()'は 'finally'文の呼び出しを保証しない唯一のシナリオです:* "exitハンドラとfinally節などは実行されません。* –

+0

@RikPoggi [' os._exit'](https://docs.python.org/library/os.html#os。 _exit)が使用されることがあります。クリーンアップハンドラを呼び出さずにPythonプロセスを終了します。 –

18

はい。

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

..isかなり相当する:より正確

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)より一般的には、With Statement Context Manager__exit__方法が実際のコンテキスト内からreturnが発生した場合に呼び出されます

+13

'finally'キーウォッドから得られる保証を示す興味深い実験は次のとおりです:' def test():try:return True;最後に:False'を返します。 –

4

。これは、次のように試験できる:

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にもかかわらず、呼び出されたことを確認しました。そのため、コンテキストマネージャはバイパスされません。

関連する問題