这就是我想要做的事情:
@MyDecorator
def f():
pass
for d in f.decorators:
print d
答案 0 :(得分:3)
如果没有装饰者的合作,这通常是不可能的。例如,
def my_decorator(f):
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
wrapper.decorators = [wrapper]
if hasattr(f, 'decorators'):
wrapper.decorators.extend[f.decorators]
return wrapper
基本上,所有装饰器都像往常一样包装函数,然后在包装器函数上放置一个decorators属性。然后它检查包装函数是否有类似的列表并向上传播。
虽然
这是无用的我想要的是
def my_decorator(f):
def wrapper(args):
return f(args)
wrapper.decorated = f
return wrapper
这将允许你做像
这样的事情@my_other_decorator # another decorator following the same pattern
@my_decorator
def foo(args):
print args
foo.decorated(args) # calls the function with the inner decorated function (my_decorator)
foo.decorated.decorated(args) # original function
您实际上可以将此模式抽象为装饰器
def reversable(decorator):
def wrapper(func):
ret = decorator(func) # manually apply the decorator
ret.decorated = func # save the original function
return ret
return wrapper
现在,当你在写装饰时:
@reversable
def my_decorator(f):
def wrapper(x):
return f(x + 1)
return wrapper
答案 1 :(得分:1)
@MyDecorator
语法只是编写以下Python代码的简写:
def f():
pass
f = MyDecorator(f)
以这种形式编写,您可以看到应用于该函数的装饰器不会以任何方式跟踪。你可以让你的装饰者在他们被应用时记住(Aaron's answer有一些关于如何做到这一点的好主意),但是你必须用你自己的所有第三方装饰者包装