2011-09-27 11 views
0

私はデコレータの機能を理解しようとしています。次のコードで何が間違っているのですか?それを修正してください。デコレータのpython

私が理解しているように、aFunction()が呼び出されると、これもまた、myDecorator()を呼び出して、これもまた、afunction()を呼び出します。右? __init__

また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、次いで__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() 
関連する問題