2017-08-28 1 views
2

je le code suivant: Un décorateur:Utilisation de la méthode de classe d'origine après avoir été décorée nécessite l'instance d'objet en tant que paramètre

def pyDecorator(func): 
    print func 
    @wraps(func) 
    def wrapped(*args, **kwargs): 
     print args 
     print kwargs 
     tBegin = time() 
     result = func(*args, **kwargs) 
     tEnd = time() 
     if result: 
      # UI update 
      print("\nTBegin '{}'({} s)".format(func.__name__, tBegin)) 
      # UI and report update 
      print("TEnd '{}' ({} s) ({} s) Result:{}".format(func.__name__, tEnd,tEnd - tBegin, result)) 
     return result 
    #workarround to use the original function 
    wrapped._original=func 
    return wrapped 

Et une méthode de classe décorée:

class Dummy(object): 
    @pyDecorator 
    def ClassMethod(self): 
     print "Original class code executed" 
     return True 

Si je appelez la méthode pour la fonction d'origine de la manière suivante, je reçois cette erreur "TypeError: ClassMethod() takes exactly 1 argument (0 given):"

ClassInstance.ClassMethod._original() 

Je suis obligé d'utiliser l'appel suivant:

ClassInstance.ClassMethod._original(ClassInstance) 

Est-il possible de le faire comme dans la première manière? Je ne comprends pas pourquoi je devrais mettre l'instance de classe en paramètre quand elle est déjà fournie.

Répondre

1

ClassInstance.ClassMethod._original est une fonction non liée à une instance de classe.

Notez que la transformation de fonction en méthode se produit lorsqu'un objet de fonction est accédé via une instance de classe, par exemple en utilisant une référence de point. Ici cependant, _original est seulement lié à un autre objet de fonction wrapper (élevé à une méthode liée à l'exécution) pas à une instance de classe. Un paramètre self implicite n'est donc pas passé. Vous devrez le passer explicitement.

ClassInstance.ClassMethod._original 
^ 
|- instance ^   
       |- method 
         ^
          |- function object bound to method 

Je ne comprends pas pourquoi je devrais mettre l'instance de classe comme paramètre quand il est déjà prévu

Non, ce n'est pas déjà fourni.

+0

En fait il n'y a pas de paramètre self * implicite *. Passer n'importe quel argument fonctionnera parce que ce que vous obtenez est une fonction qui prend un argument. – styvane

+0

@sstyvane Oui, fonctionne avec un seul argument. * Passer n'importe quel argument fonctionnera *, bien, si l'argument implémente l'interface requise (comme une instance de Dummy) comme requis par la fonction lors de l'exécution, bien que 'self' ne soit jamais utilisé dans la fonction ici. –