0

関数デコレータのチェーンを作成する方法を説明していますか? デコレータを理解する。

次の例では、クロージャが原因で「method_to_decorate」がラッパー関数にアクセスできることがわかります。selfしかし、引数とlieラッパー関数にアクセスする方法がわかりませんでした。

def method_friendly_decorator(method_to_decorate):
     def wrapper(self, lie):
         lie = lie - 3 # very friendly, decrease age even more :-)
         return method_to_decorate(self, lie)
     return wrapper

class Lucy(object):

    def __init__(self):
        self.age = 32

    @method_friendly_decorator
    def sayYourAge(self, lie):
        print "I am %s, what did you think?" % (self.age + lie)

l = Lucy()
l.sayYourAge(-3)
#outputs: I am 26, what did you think?
4

1 に答える 1

6

返さwrapperれた関数は装飾された関数を置き換えるため、メソッドとして扱われます。オリジナルsayYourAgeが取っ(self, lie)たので、新しいものもそうwrapperです。

したがって、呼び出すl.sayYouAge(-3)ときは、実際にはネストされた関数を呼び出していますwrapper。これは、その時点ではバインドされたメソッドです。バインドされたメソッドがself渡され、-3引数に割り当てられますliewrapperを呼び出しmethod_to_decorate(self, lie)、これらの引数を元の装飾された関数に渡します。

selfとは署名lieにハードコードされていることに注意してください。wrapper()それは装飾された機能にしっかりと結びついています。これらは装飾された関数から取得されたものではなく、ラッパーを作成したプログラマーは、ラップされたバージョンにどのような引数が期待されるかを事前に知っていました。ラッパーは、引数を装飾された関数とまったく一致させる必要がないことに注意してください。

たとえば、引数を追加できます。

def method_friendly_decorator(method_to_decorate):
     def wrapper(self, lie, offset=-3):
         lie += offset # very friendly, adjust age even more!
         return method_to_decorate(self, lie)
     return wrapper

これで、ルーシーにさまざまな方法で彼女の年齢について嘘をつくことができます。

l.sayYourAge(-1, offset=1)  # will say "I am 32, what did you think?"
于 2013-01-11T11:08:21.243 に答える