【发布时间】:2020-04-09 21:13:30
【问题描述】:
我想将上下文装饰器与使用或不使用参数的可能性结合起来。
让我们从一个可以带参数和不带参数的装饰器开始,例如:
import functools
def decorator(func=None, *, label=""):
if func is None:
return functools.partial(decorator, label=label)
@functools.wraps(func)
def wrap(*args, **kwargs):
result = func(*args, **kwargs)
print(f"RESULT {label}: {result}")
return result
return wrap
if __name__ == "__main__":
@decorator(label="with arguments")
def dec_args():
return 1
@decorator
def dec_no_args():
return 0
dec_args()
dec_no_args()
还有ContextDecorator 可以用作上下文管理器或装饰器:
from contextlib import ContextDecorator
class ctxtdec(ContextDecorator):
def __init__(self, label:str=""):
self.label = label
print(f"initialized {self.label}")
def __enter__(self):
print(f"entered {self.label}")
def __exit__(self, exc_type, exc_value, traceback):
print(f"exited {self.label}")
if __name__ == "__main__":
def testfunc():
for n in range(10 ** 7):
n ** 0.5
@ctxtdec("decorated")
def decorated():
testfunc()
with ctxtdec("square rooting"):
testfunc()
decorated()
但我也希望它也能正常工作:
@ctxtdec
def decorated():
testfunc()
【问题讨论】:
-
虽然有可能,但它可能会很麻烦,因为您可能需要弄乱元类以确保它既可以用作装饰器,也可以用作带有和不带 args 的上下文管理器。使用
@cxtdec()有什么问题? -
我想摆脱
(),仅此而已
标签: python decorator contextmanager