這是我的工作代碼:如何將裝飾器與@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
的問題是,@with_report_status
不屈服,通過@contextmanager
預期。但是,我無法以其他方式換行,因爲@contextmanager
會返回一個生成器對象(我認爲!)而不是該值本身。
我怎樣才能讓@contextmanager
與裝飾者一起玩呢?
實際上,open()以相同的方式工作,用作上下文管理器或類。所以它是有道理的,而且這是可能的。 – 2012-07-23 09:39:53