注意一下代碼:spa
def try_method(): try: print('code started') raise KeyError return 1 except KeyError as e: print('keyerror') return 2 finally: print('finally') return 4 s = try_method() print(s) 輸出結果: code started keyerror finally 4
關於最後結果爲什不是2?code
在except語句中是捕捉到了KeyError錯誤。return2,此時會將結果2壓入到棧中,而後會繼續執行finally語句,finally語句return4後繼續壓入到棧中,而後s的值爲從棧中取出blog
的值,即爲4而不是2,若是finally最後沒有reuturn結果,那麼s的值就爲2。資源
要使得本身定義的類知足上下文管理器協議,類中必須定義一下連個魔法方法:it
1:__enter__()class
2:__exit__()import
例:file
class Sample(): def __enter__(self): print('Enter') return self def __exit__(self, exc_type, exc_val, exc_tb): print('Exit') def do_something(self): print('doing something') with Sample() as s: s.do_something() 輸出結果: Enter doing something Exit
用with調用類開始調用的時候,會執行__enter__()方法,調用完成退出的時候必定會執行類中的__exit__()方法。因而最後悔打印出Exit。利用此能夠在__enter__()方法中獲取資源, 而後再__exit__()中釋放資源。yield
更加簡單的方式用contextlib:方法
import contextlib @contextlib.contextmanager def open(file_name): print('file wil be opened') yield 'something' print('file ended') with open('**.txt') as f: print('file processing') 輸出結果: file wil be opened file processing file ended
在yield語句以前語句就至關於__enter__()內的語句。yield以後的語句至關於__exit__()內的語句。所以都會會執行file ended。