我正在尝试编写一个可以与with
关键字一起使用的装饰器。
# regular code ...
with my_exception_handler():
# dangerous code ...
# regular code ...
并且my_exception_handler将接收一个函数并将其包装在一个巨大的try-except。
中我想让它成为一个装饰器/包装器,因为它是很多我不想复制粘贴的代码。我无法弄清楚从哪里开始。我写了一个普通的装饰器,它适用于函数,但不适用于中间代码块。
答案 0 :(得分:5)
你与with
一起使用的东西是一个上下文管理器而不是一个装饰器 - 这两个是完全不同的东西。
with
和上下文管理员的工作方式,请参阅http://docs.python.org/release/2.5/whatsnew/pep-343.html。编辑:请参阅kindall的帖子,了解如何编写简单的上下文管理器,而不必使用完整的类;我没有时间用这样的例子修改我的答案:)
答案 1 :(得分:2)
您需要编写上下文管理器,而不是装饰器。您可以使用contextlib.contextmanager
装饰器轻松完成您想要的操作。
from contextlib import contextmanager
@contextmanager
def my_exception_handler():
try:
yield # execute the code in the "with" block
except Exception as e:
# your exception-handling code goes here
print e
# try it out
with my_exception_handler():
raise ValueError("this error has value")
答案 2 :(得分:0)
在了解了上下文管理器之后,我采用了extended traceback function并将其转换为装饰器和上下文管理器,其中包含以下几个片段:
def traceback_decorator(function):
def wrap(*args, **kwargs):
try:
return function(*args, **kwargs)
except:
print_exc_plus()
def traceback_wrapper(function=None, *args, **kwargs):
context = _TracebackContext()
if function is None:
return context
with context:
function(*args, **kwargs)
class _TracebackContext(object):
def __enter__(self):
pass
def __exit__(self, exc_type, exc_value, traceback):
if exc_type:
print_exc_plus()