我想扩展一个库的装饰器。我知道我可以调用两个装饰器:
@my_decorator
@lib_decorator
def func():
pass
但我想避免每次都将@lib_decorator
传递给每个函数。我希望我的装饰者能够使用func()
自动装饰lib_decorator
。我怎样才能做到这一点?它们可以嵌套吗?
答案 0 :(得分:3)
您可以将lib的装饰器合并到您的内部。对于简单的无参数装饰器,它是相当简单的:
def my_decorator():
@lib_decorator # <--- Just include the lib's decorator here
def inner:
func(*args, **kwargs)
return inner
对于有参数的装饰者来说,这有点棘手。请记住,你的装饰器正在用最内层函数替换装饰函数。这就是你需要装饰的那个。所以如果你用args打电话给你的装饰者,例如
@my_decorator(arg)
def func():
pass
然后用lib装饰器装饰内部函数:
def my_decorator(arg):
def wrapper(func):
@lib_decorator # <--- Just include the lib's decorator here
def inner(*args, **kwargs):
func(*args, **kwargs)
return inner
return wrapper
或者,使用装饰器函数的class
形式:
class my_decorator():
def __init__(self, arg):
pass
def __call__(self, func):
@lib_decorator # <--- Just include the lib's decorator here
def inner(*args, **kwargs):
func(*args, **kwargs)
return inner
答案 1 :(得分:1)
您可以轻松转换像您这样的装饰:
@my_decorator
@lib_decorator
def func():
pass
对于这种更简单的装饰,使用功能组合:
my_composed_decorator = lambda func: my_decorator(lib_decorator(func))
@my_composed_decorator
def func():
pass