2008-11-11 115 views
9

我有一個由別人編寫的相當複雜的裝飾器。我想要做的是根據一個決定調用一次函數的裝飾版本,或者再次調用原始函數(未裝飾)。這可能嗎?調用之前的Python裝飾函數

回答

26

隨着:

decorator(original_function)() 

無:

original_function() 

裝飾器僅僅是一個函數,它接受一個函數作爲參數並返回另一個。 @語法完全是可選的。也許篩選一些documentation可能有助於澄清事情。

+0

鏈接損壞:( – 2015-09-19 14:48:01

2
def original_function(): 
    pass 

decorated_function= decorator(original_function) 

if use_decorated: 
    decorated_function() 
else: 
    original_function() 

只裝飾一次,然後選擇要調用的版本。

1

這裏是我提出的問題的食譜。我還需要保持簽名相同,所以我使用了裝飾模塊,但是您可以重新夾緊以避免這種情況。基本上,訣竅是給函數添加一個屬性。 '原始'函數沒有綁定,所以你需要傳入一個'self'作爲第一個參數,所以我添加了一些額外的代碼來檢查。

# http://www.phyast.pitt.edu/~micheles/python/decorator-2.0.1.zip 
from decorator import decorator, update_wrapper 

class mustbe : pass 

def wrapper (interface_) : 
    print "inside hhh" 
    def call (func, self, *args, **kwargs) : 
     print "decorated" 
     print "calling %s.%s with args %s, %s" % (self, func.__name__, args, kwargs) 
     return interface_ (self, *args, **kwargs) 
    def original (instance , *args, **kwargs) : 
     if not isinstance (instance, mustbe) : 
      raise TypeError, "Only use this decorator on children of mustbe" 
     return interface_ (instance, *args, **kwargs) 
    call = decorator (call, interface_) 
    call.original = update_wrapper (original, call) 
    return call 

class CCC (mustbe): 
    var = "class var" 
    @wrapper 
    def foo (self, param) : 
     """foo""" 
     print self.var, param 

class SSS (CCC) : 
    @wrapper (hidden_=True) 
    def bar (self, a, b, c) : 
    print a, b, c 

if __name__ == "__main__" : 
    from inspect import getargspec 

    print ">>> i=CCC()" 
    i=CCC() 

    print ">>> i.var = 'parrot'" 
    i.var = 'parrot' 

    print ">>> i.foo.__doc__" 
    print i.foo.__doc__ 

    print ">>> getargspec(i.foo)" 
    print getargspec(i.foo) 

    print ">>> i.foo(99)" 
    i.foo(99) 

    print ">>> i.foo.original.__doc__" 
    print i.foo.original.__doc__ 

    print ">>> getargspec(i.foo.original)" 
    print getargspec(i.foo.original) 

    print ">>> i.foo.original(i,42)" 
    i.foo.original(i,42) 

    print ">>> j=SSS()" 
    j=SSS() 

    print ">>> j.bar(1,2,3)" 
    j.bar(1,2,3)