contextlib模块:上下文管理器工具
简单实现with...as...
as是__enter__返回的对象
__exit__返回True,则不抛出异常,返回False,则抛出异常
class WithinContext: def __init__(self, context): print('Within.__init__: ', context) def do_something(self): print('Within.do_something') raise RuntimeError('error message') def __del__(self): print('Within.__del__') class Context: def __init__(self, handle_error): print('Contexxt.__init__(%s)' % handle_error) self.handle_error =handle_error def __enter__(self): print('Within.__enter__') return WithinContext(self) def __exit__(self, exc_type, exc_val, exc_tb): print('Within.__exit__') print(' exc_type:',exc_type) print(' exc_val:', exc_val) print(' exc_tb:', exc_tb) return self.handle_error with Context(True) as c: c.do_something()
with Context(False) as c:
c.do_something()
@contextlib.contextmanager
@contextlib.contextmanager def make_context(): print(' entering') try: yield {} except RuntimeError as e: print(' ERROR:', e) finally: print(' exiting') with make_context() as value: print(' inside with statement:', value) # raise RuntimeError('showing RuntimeError') raise ValueError('this is not handled')
嵌套上下文
@contextlib.contextmanager def make_context(name): print(' entering: ', name) try: yield name except RuntimeError as e: print(' ERROR:', e) finally: print(' exiting: ', name) with make_context('A') as A, make_context('B') as B: print(' inside with statement:', A, B)
closing() 管理有close()的遗留类
class Door: def __init__(self): print(' __init__') def close(self): print(' close()') try: with contextlib.closing(Door()) as d: print(' raising inside with') raise RuntimeError('error message') except Exception as e: print(' had an error:', e)