2010-10-14 23 views

回答

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 

本质上,所有的装饰作用是包裹功能照常,然后把一个上装饰包装函数属性。然后它检查包装的函数是否有类似的列表并向上传播。

这是相当无用虽然

想你想

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 
+0

请注意,Python 3.2的'functools.wraps'使用'__wrapped__'来指向原始函数。我建议使用相同的名称,因此代码可以停止在此上发散。 (我也需要开始这样做;我一直使用“func”这个名字。)我推荐实际使用'functools.wraps',但这并不是一个解决方案,直到3.2被广泛使用。 – 2010-10-14 01:38:32

1

@MyDecorator语法只是写了下面的Python代码的缩写:

def f(): 
    pass 
f = MyDecorator(f) 

写在这种形式下,你可以看到装饰应用于该功能的信息不会以任何方式跟踪。你可能让你的装饰者在应用时记得(Aaron's answer有一些关于如何做到这一点的好主意),但是你必须用自己的方式包装所有第三方装饰者。

相关问题