2010-10-14 19 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有一些關於如何做到這一點的好主意),但是你必須用自己的方式包裝所有第三方裝飾者。

相關問題