Chr*_*s R 5 python decorator contextmanager
这是我正在使用的代码:
from contextlib import contextmanager
from functools import wraps
class with_report_status(object):
def __init__(self, message):
self.message = message
def __call__(self, f):
@wraps(f)
def wrapper(_self, *a, **kw):
try:
return f(_self, *a, **kw)
except:
log.exception("Handling exception in reporting operation")
if not (hasattr(_self, 'report_status') and _self.report_status):
_self.report_status = self.message
raise
return wrapper
class MyClass(object):
@contextmanager
@with_report_status('unable to create export workspace')
def make_workspace(self):
temp_dir = tempfile.mkdtemp()
log.debug("Creating working directory in %s", temp_dir)
self.workspace = temp_dir
yield self.workspace
log.debug("Cleaning up working directory in %s", temp_dir)
shutil.rmtree(temp_dir)
@with_report_status('working on step 1')
def step_one(self):
# do something that isn't a context manager
Run Code Online (Sandbox Code Playgroud)
问题是,@with_report_status不屈服,正如预期的那样@contextmanager。但是,我也不能以相反的方式包装它,因为@contextmanager返回一个生成器对象(我认为!)而不是值本身。
我怎样才能让@contextmanager装饰者玩得开心?
这是一个奇怪的问题:@contextmanager返回一个上下文管理器,而不是一个生成器。但出于某种原因,您想将上下文管理器视为函数?这不是你可以做的事情,它们没有任何共同点。
我认为你想要的是一个MyClass.make_workspace上下文管理器,并且还有一个report_status字段以防异常。为此,您需要自己编写一个上下文管理器,在其__exit__方法中设置此字段,@contextmanager这里无法帮助您。
您可以子类化contextlib.GeneratorContextManager以避免大部分工作。它没有记录,所以请使用来源,卢克。
| 归档时间: |
|
| 查看次数: |
3063 次 |
| 最近记录: |