Question

J'ai un décorateur assez complexe écrit par quelqu'un d'autre. Ce que je veux faire, c'est appeler une version décorée de la fonction une fois basée sur une décision ou appeler la fonction d'origine (non décorée) une autre fois. Est-ce possible?

Était-ce utile?

La solution

Avec:

decorator(original_function)()

Sans:

original_function()

Un décorateur est juste une fonction qui prend une fonction en argument et en retourne un autre. La syntaxe @ est totalement optionnelle. Peut-être qu'une sélection de la documentation pourrait aider à clarifier les choses.

Autres conseils

def original_function():
    pass

decorated_function= decorator(original_function)

if use_decorated:
    decorated_function()
else:
    original_function()

Décorez une seule fois, puis choisissez la version à appeler.

Voici la recette que j'ai proposée pour le problème. J'avais aussi besoin de garder les signatures identiques alors j'ai utilisé le module décorateur mais vous pouvez re-gabarir pour éviter cela. Fondamentalement, l'astuce consistait à ajouter un attribut à la fonction. La fonction "originale" étant non liée, vous devez donc indiquer un "self" en tant que premier paramètre. J'ai donc ajouté du code supplémentaire pour le vérifier également.

# 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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top