Bien qu'il y ait plenty of resources about using classes as decorators, je n'ai pas été en mesure de trouver tout ce qui traitent le problème de la décoration méthodes. Le but de cette question est de régler cela. Je vais poster ma propre solution, mais bien sûr, tout le monde est invité à poster le leur aussi.En utilisant des classes comme décorateurs de méthode
Pourquoi la mise en œuvre « standard » ne fonctionne pas
Le problème avec l'implémentation standard de classe décorateur est que Python ne crée pas une méthode liée de la fonction décorée:
class Deco:
def __init__(self, func):
self.func= func
def __call__(self, *args):
self.func(*args)
class Class:
@Deco
def hello(self):
print('hello world')
Class().hello() # throws TypeError: hello() missing 1 required positional argument: 'self'
Un décorateur de méthode doit surmonter cet obstacle.
Exigences
Prendre les classes de l'exemple précédent, les choses suivantes devraient travailler:
>>> i= Class()
>>> i.hello()
hello world
>>> i.hello
<__main__.Deco object at 0x7f4ae8b518d0>
>>> Class.hello is Class().hello
False
>>> Class().hello is Class().hello
False
>>> i.hello is i.hello
True
Idéalement, __doc__
et signature et attributs similaires de la fonction sont conservés aussi bien.
Également pertinent: [Meilleure pratique du décorateur Python, utilisation d'une classe par rapport à une fonction] (http://stackoverflow.com/questions/10294014/python-decorator-best-practice-using-a-class-vs-a- function) –
Pourquoi voulez-vous que ce soit un cours? Quel est le problème avec le décorateur juste une fonction? –
@PaulRooney Dans mon cas particulier (j'écris une bibliothèque GUI), je veux stocker un tas d'attributs sur la fonction (comme raccourci clavier, description, catégorie, etc.) et aussi un tas de fonctions (comme '. start_in_new_thread() ',' .update_status() '). Au lieu de forcer tous ces attributs sur la fonction, je préfère écrire une classe wrapper et remplacer complètement la fonction. –