2011-09-27 96 views
0

我想了解裝飾器的功能。我在下面的代碼中做錯了什麼。請糾正它python中的裝飾器

正如我瞭解,當aFunction()被調用時,它又調用myDecorator(),它也調用afunction()。對?

另外如何傳遞參數代入機能缺失()

class myDecorator(object): 

    def __init__(self, f): 
     print "inside myDecorator.__init__()" 
     f(1) # Prove that function definition has completed 

    def __call__(self): 
     print "inside myDecorator.__call__()" 

@myDecorator 
def aFunction(*a): 
    print a 
    print "inside aFunction()" 

print "Finished decorating aFunction()" 

aFunction(2) 
+2

詳盡的解釋:http://stackoverflow.com/questions/739654/understanding-python-decorators – rplnt

+0

如果您需要裝飾和註解更多的幫助,在這裏看到我的博客文章。 http://blog.mattalcock.com/2013/1/5/decorates-and-annotations/ –

回答

1

f,在__init__,需要保存,則__call__方法需要調用它。事情是這樣的:

class myDecorator(object): 
    def __init__(self, f): 
     print "inside myDecorator.__init__()" 
     self.f = f 
     print "function has been saved" 
    def __call__(self, *args): 
     print "inside myDecorator.__call__()" 
     result = self.f(args) 
     print "done with f()" 
     return result 

@myDecorator 
def aFunction(*a): 
    print a 
    print "inside aFunction()" 

aFunction(1) 

與裝飾會發生什麼情況是,原來的功能是取代與任何裝飾的回報。但是,您的原始代碼並未保存對aFunction的任何引用,因此它已丟失。

+0

可以請你給這個示例代碼.. – Rajeev

+1

你假設任何裝飾函數不帶關鍵字參數。 – agf

+0

@agf,不,我知道他沒有,因爲他沒有在那裏。編寫最常見的案例並不總是必要的。 –

2

您的__call__方法缺少您給aFunction的參數。這裏

class myDecorator(object): 

    def __init__(self, f): 
     print "inside myDecorator.__init__()" 
     f(1) # Prove that function definition has completed 
     self.__function = f 

    def __call__(self, *args): 
     # the *args magic is here to mirror the original parameter list of 
     # the decorated function. But it is better to place here parameter list 
     # of the function you want to decorate, in order to minimize error possibilities 
     print "inside myDecorator.__call__()" 
     return self.__function(*args) 

@myDecorator 
def aFunction(*a): 
    print a 
    print "inside aFunction()" 

print "Finished decorating aFunction()" 

aFunction(1) 
aFunction('a', 23, 42) 
+0

可以請你給這個示例代碼.. – Rajeev

+1

你應該從__call__'返回函數的結果。也很可能不需要在這裏使用名稱修飾 - 您甚至可能希望人們能夠訪問包裝的功能。你假設這個函數不帶任何關鍵字參數。 – agf

+0

@agf我同意返回,但是對於函數成員的「可見性」和函數參數,它取決於真實環境。 – Rudi

4
class myDecorator(object): 

    def __init__(self, f): 
     print "inside myDecorator.__init__()" 
     # save a reference to the real function, so it can be called later 
     self.f = f 

    def __call__(self, *args, **kwargs): 
     print "inside myDecorator.__call__()" 
     # call the real function and return its result 
     # passing it any and all arguments 
     return self.f(*args, **kwargs) 

@myDecorator 
def aFunction(*a): 
    print a 
    print "inside aFunction()" 

print "Finished decorating aFunction()" 

aFunction(1) 

print "Finished calling aFunction()