<p>通过组合<code>contextmanager</code>用于管理其上下文的类(<code>_GeneratorContextManager</code>)和<code>ContextDecorator</code>类,可以轻松地实现所需的功能。例如</p>
<pre><code>from contextlib import ContextDecorator, _GeneratorContextManager
from functools import wraps
class MyContextManager(_GeneratorContextManager, ContextDecorator):
pass
def contextmanager(func):
@wraps(func)
def helper(*args, **kwds):
return MyContextManager(func, args, kwds)
return helper
@contextmanager
def print_bar_on_error():
try:
yield
except:
print('bar')
raise
with print_bar_on_error():
raise Exception('baz gone bar in context manager')
</code></pre>
<p>产生:</p>
^{pr2}$
<p>当装饰用的时候</p>
<pre><code>@print_bar_on_error()
def bazzer():
raise Exception('baz gone bar in decorator')
bazzer()
</code></pre>
<p>产生:</p>
<pre><code>bar
Traceback (most recent call last):
File "run.py", line 32, in <module>
bazzer()
File "c:\Users\User\AppData\Local\Programs\Python\Python35-32\lib\contextlib.py", line 30, in inner
return func(*args, **kwds)
File "run.py", line 31, in bazzer
raise Exception('baz gone bar in decorator')
Exception: baz gone bar in decorator
return func(*args, **kwds)
Exception: baz gone bar in decorator
</code></pre>