2017-08-28 46 views
2

我有以下代碼: 裝飾器:用法要求對象實例作爲參數

def pyDecorator(func): 
    print func 
    @wraps(func) 
    def wrapped(*args, **kwargs): 
     print args 
     print kwargs 
     tBegin = time() 
     result = func(*args, **kwargs) 
     tEnd = time() 
     if result: 
      # UI update 
      print("\nTBegin '{}'({} s)".format(func.__name__, tBegin)) 
      # UI and report update 
      print("TEnd '{}' ({} s) ({} s) Result:{}".format(func.__name__, tEnd,tEnd - tBegin, result)) 
     return result 
    #workarround to use the original function 
    wrapped._original=func 
    return wrapped 

而一個裝飾類方法:

class Dummy(object): 
    @pyDecorator 
    def ClassMethod(self): 
     print "Original class code executed" 
     return True 

如果我以下列方式調用原函數的方法,我收到此錯誤"TypeError: ClassMethod() takes exactly 1 argument (0 given):"

ClassInstance.ClassMethod._original() 

所以我不得不使用下面的調用:

ClassInstance.ClassMethod._original(ClassInstance) 

是否有可能這樣做,因爲在第一種方式?我不明白爲什麼我應該把類實例作爲參數提供。

回答

1

ClassInstance.ClassMethod._original是一個不綁定到任何類實例的函數。

請注意,從函數到方法的轉換髮生在通過類實例訪問函數對象時,比如使用點引用。然而,在這裏,_original僅綁定到另一個函數對象wrapper(在運行時提升爲綁定方法)而不綁定到類實例。因此不會傳遞隱含的self參數。你必須明確地通過它。

ClassInstance.ClassMethod._original 
^ 
|- instance ^   
       |- method 
         ^
          |- function object bound to method 

我不明白爲什麼我應該把類的實例作爲參數 時,它已經提供

不,它不是已經提供。

+0

實際上,甚至沒有*隱式'self'參數*。傳遞任何參數都是可行的,因爲你得到的是一個帶有一個參數的函數。 – styvane

+0

@sstyvane是的,具有單一參數的函數。 *如果參數在運行時按照函數的要求實現所需的接口(如'Dummy'實例),則傳遞任何參數都可以工作,儘管此處函數從未使用過「self」。 –