9

私は他の誰かによって書かれたかなり複雑なデコレータを持っています。私がやりたいことは、決定に基づいて関数の装飾されたバージョンを1回呼び出すか、元の関数(装飾されていない)を別の時間に呼び出すことです。これは可能ですか?

4

3 に答える 3

26

と:

decorator(original_function)()

それなし:

original_function()

デコレータは、関数を引数として受け取り、別の関数を返す単なる関数です。@ 構文は完全にオプションです。おそらく、いくつかのドキュメントをふるいにかけると、物事を明確にするのに役立つかもしれません。

于 2008-11-11T22:45:52.243 に答える
2
def original_function():
    pass

decorated_function= decorator(original_function)

if use_decorated:
    decorated_function()
else:
    original_function()

一度だけ装飾し、その後どのバージョンを呼び出すかを選択します。

于 2008-11-12T02:26:08.490 に答える
1

これが私が問題に対して思いついたレシピです。また、署名を同じに保つ必要があったため、decorator モジュールを使用しましたが、それを回避するために再ジグすることができました。基本的に、トリックは関数に属性を追加することでした。「元の」関数はバインドされていないため、最初のパラメーターとして「self」を渡す必要があるため、それを確認するためのコードを追加しました。

# http://www.phyast.pitt.edu/~micheles/python/decorator-2.0.1.zip
from decorator import decorator, update_wrapper

class mustbe : pass

def wrapper ( interface_ ) :
    print "inside hhh"
    def call ( func, self, *args, **kwargs ) :
        print "decorated"
        print "calling %s.%s with args %s, %s" % (self, func.__name__, args, kwargs)
        return interface_ ( self, *args, **kwargs )
    def original ( instance , *args, **kwargs ) :
        if not isinstance ( instance, mustbe ) :
            raise TypeError, "Only use this decorator on children of mustbe"
        return interface_ ( instance, *args, **kwargs )
    call = decorator ( call, interface_ )
    call.original = update_wrapper ( original, call )
    return call

class CCC ( mustbe ):
    var = "class var"
    @wrapper
    def foo ( self, param ) :
        """foo"""
        print self.var, param

class SSS ( CCC ) :
  @wrapper ( hidden_=True )
  def bar ( self, a, b, c ) :
    print a, b, c

if __name__ == "__main__" :
    from inspect import getargspec

    print ">>> i=CCC()"
    i=CCC()

    print ">>> i.var = 'parrot'"
    i.var = 'parrot'

    print ">>> i.foo.__doc__"
    print i.foo.__doc__

    print ">>> getargspec(i.foo)"
    print getargspec(i.foo)

    print ">>> i.foo(99)"
    i.foo(99)

    print ">>> i.foo.original.__doc__"
    print i.foo.original.__doc__

    print ">>> getargspec(i.foo.original)"
    print getargspec(i.foo.original)

    print ">>> i.foo.original(i,42)"
    i.foo.original(i,42)

    print ">>> j=SSS()"
    j=SSS()

    print ">>> j.bar(1,2,3)"
    j.bar(1,2,3)
于 2009-05-01T18:57:04.217 に答える