4
class myDecorator(object):

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

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

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

def main():
    print "main starts....."
    aFunction()
    print "main ends....."

出力:

inside myDecorator.__init__()
inside aFunction()
main starts.....
inside myDecorator.__call__()
main ends.....

上記のコードについて、次の点が理解できませんでした。

  1. 「メインの開始....」が最初の行に印刷されないのはなぜですか?

  2. aFunction() から何らかの値を返す場合、 not に置き換えaFunction()られるため、その呼び出しの代わりに使用できないとします。inside myDecorator.__call__()inside aFunction()

4

2 に答える 2

6

デコレータの構文:

@myDecorator
def aFunction():
    …

これと同等です:

def aFunction():
    …
aFunction = myDecorator(aFunction)

がクラスの場合、関数が定義されたときに呼び出されるmyDecoratorことが期待されます。__init__次に、クラスのインスタンスが関数の代わりに使用されます。あなたがそれを呼び出すとき、あなたは呼び出されることを期待__call__するので、そこに呼び出しf()が行くべきです。

于 2013-06-03T13:51:13.077 に答える
2

Python での関数定義

def foo():
    pass

実際には、(疑似コード)* のようなことを言うプログラマーフレンドリーな方法です:

foo = function(code=compile('pass', ...), globals=globals(), name='foo')

そのため、ラッパーは単に間に入ります:

foo = my_wrapper(function(...))

ラッパーがクラスの場合、__init__呼び出されます。関数の場合は呼び出されます。このステートメントの後、すべてが通常どおり機能します。


*この疑似コードは実際のコードからそれほど離れていません:

>>> def bar(): pass
...
>>> body = compile('print("hello")', '', 'exec')
>>> function = type(bar)
>>> foo = function(body, globals(), 'foo')
>>> foo()
hello
于 2013-06-03T13:51:39.190 に答える