0

正しい構文は何ですか?

プログラミングの試み

class Foo:
    def hello(self):
        print "Hello cruel world!"
 
    def greet_first(self, f):
        self.hello()
        return lambda *args, **kwargs: f(*args, **kwargs)
 
    @greet_first
    def goodbye(self, concat):
        print "Goodbye {0}".format(concat)
 
if __name__=='__main__':
    bar = Foo()
    bar.goodbye(' and thanks for all the fish')

デバッグ

Traceback (most recent call last):
  File "prog.py", line 1, in <module>
    class Foo:
  File "prog.py", line 9, in Foo
    @greet_first
TypeError: greet_first() takes exactly 2 arguments (1 given)

参照

クリックしてコードを実行 (IDEone)

4

1 に答える 1

2

デコレータはすぐに呼び出され、のメソッドとしては扱われず、Foo代わりにローカル関数として表示されます。@greet_first構文は事実上次のことを意味します。

 goodbye = greet_first(goodbye)

すぐに実行されます。これはバインドされたメソッドではないため、パラメーターselfは含まれていません。greet_firstメソッドを作成しても意味がありません。selfそれを移動して、引数を完全に削除します。

置き換える呼び出し可能オブジェクトを返すようにデコレータを調整する必要がありますgoodbye

def greet_first(f):
    def wrapper(self, *args, **kwargs):
        self.hello()
        return f(self, *args, **kwargs)
    return wrapper

self.hello()呼び出されるたびgoodbyeに呼び出されます。

の一部を作成する必要ある場合は、デコレータを使用できますが、他のメソッド宣言に使用できるようにするために、追加のフープをジャンプする必要があります。あなたはそれがなった記述子としてそれを扱いそしてそれを要求しなければなりません:greet_firstFoo@staticmethod.__get__()

class Foo(object):
    def hello(self):
        print "Hello cruel world!"

    @staticmethod
    def greet_first(f):
        def wrapper(self, *args, **kwargs):
            self.hello()
            return f(self, *args, **kwargs)
        return wrapper

    @greet_first.__get__(object)
    def goodbye(self, concat):
        print "Goodbye {0}".format(concat)

とにかくその引数を無視.__get__()するので、私は任意のタイプ(objectこの場合)で呼び出します。その定義の一部であるコード内でそのクラスがまだファイナライズされていないため、ここでは使用できません。staticmethod Foo

@staticmethodまったく機能させるには、Python2で継承する必要があることに注意してくださいobject

于 2013-02-09T13:11:54.290 に答える