注意一下代码: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。