2017-06-06 2 views
0

Cette question est en relation avec another question Je viens de poser une question.Comment est-ce que je peux envoyer la liste inconnue d'arguments à un décorateur de python - quand le décorateur est une méthode d'une classe différente?

J'ai créé un décorateur python comme indiqué ci-dessous. Je veux que ce décorateur accepte une liste inconnue d'arguments. Mais il y a une ride supplémentaire. Le décorateur est une méthode d'instance d'une autre classe:

#!/usr/bin/env python 
from functools import wraps 


class A: 

    def my_decorator(self, func=None, **kwargs): 

     def inner_function(decorated_function): 

      def wrapped_func(*fargs, **fkwargs): 
       print kwargs 
       return decorated_function(*fargs, **fkwargs) 
      return wrapped_func 

     if func: 
      return inner_function(func) 
     else: 
      return inner_function 

class B: 
    my_a = A() 

    @my_a.my_decorator(arg_1="Yolo", arg2="Bolo") 
    def my_func(): 
     print "Woo Hoo!" 


my_B = B() 
B.my_func() 

Mais ce code ne fonctionne pas ci-dessous:

Traceback (most recent call last): 
    File "./decorator_test.py", line 30, in <module> 
    B.my_func() 
TypeError: unbound method wrapped_func() must be called with B instance as first argument (got nothing instead) 

Comment résoudre ce problème?

+0

Avez-vous oublié '@ staticmethod', ici? Parce que 'my_func()' est une méthode de 'B' et nécessite un objet à appeler. Il manque également le paramètre 'self'. Ou devrait-il être 'my_B.my_func()' (dans ce cas 'self' est toujours manquant, cependant). – dhke

+0

Je voulais dire my_B.my_func() '. Pardon. J'ai corrigé les fautes de frappe et maintenant ça marche. –

Répondre

0

Voici mon approche de coder votre décorateur:

class A: 
    def __init__(self, func=None, **kargs): 
     self.args = func 
     self.kargs = kargs 
    def __call__(self, decorated_function): 
     def wrapper_func(*args, **kargs): 
      print kargs 
      return decorated_function(*args, **kwargs) 
     if self.func: 
      #..do something.. 
      return wrapper_func 
     elif 'xyz' in self.kargs: 
      #...do something else here.. 
      return wrapper_func 
     else: 
      ... 


class B: 
    @A(arg_1="Yolo", arg2="Bolo")    # A(...)(my_func) 
    def my_func(): 
     print "Woo Hoo!" 

Ceci est une façon typique des décorateurs de codage. La classe A renvoie un objet appelable lorsqu'il est appelé. L'objet appelable de la classe A sera appelé automatiquement pour la décoration. Lorsque l'objet appelable est appelé, sa méthode __call__ est déclenchée et sa méthode de surcharge d'opérateur __call__ renvoie la fonction wrapper après avoir effectué une personnalisation. La fonction wrapper est la fonction qui entoure la logique autour de votre fonction d'origine.