다음은 내가 작업하고있는 코드입니다.@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
가 예상대로 @with_report_status
를 생성하지 않는다는 것입니다. 그러나 @contextmanager
생성기 개체를 반환하기 때문에 나는 둘 중 하나를 주위에 다른 방법으로 래핑 할 수 없습니다 (나는 생각합니다!) 값 자체 대신.
@contextmanager
을 데코레이터로 멋지게 플레이하려면 어떻게해야합니까?
사실 open()은 컨텍스트 관리자 또는 클래스로 사용되는 것과 같은 방식으로 작동합니다. 그래서 그것은 의미가 있으며, 가능합니다. –