Bien que j'aime à me considérer comme un codeur Python raisonnablement compétent, un des aspects du langage que je n'ai jamais réussi à comprendre est celui des décorateurs.
Je sais ce que c'est (superficiellement), j'ai lu des tutoriels, des exemples, des questions sur Stack Overflow, et je comprends la syntaxe, je peux écrire la mienne, parfois utiliser @classmethod et @staticmethod, mais il ne m'est jamais venu à l'esprit d'utiliser un décorateur pour résoudre un problème dans mon propre code Python. Je ne rencontre jamais un problème où je pense, "Hmm ... cela ressemble à un travail pour un décorateur!"
Donc, je me demande si vous pourriez offrir des exemples où vous avez utilisé des décorateurs dans vos propres programmes, et j'espère que j'aurai un "A-ha!" moment et les obtenir .
functools.lru_cache
, qui fait exactement ce que Peter a dit, depuis Python 3.2, sorti en février 2011.Réponses:
J'utilise des décorateurs principalement à des fins de synchronisation
la source
time.clock()
mesure le temps CPU. Vous voudrez peut-être utiliser à latime.time()
place si vous souhaitez mesurer l'heure de l'horloge murale.myFunction
courir ...Je les ai utilisés pour la synchronisation.
Comme indiqué dans les commentaires, depuis Python 2.5, vous pouvez utiliser une
with
instruction en conjonction avec un objetthreading.Lock
(oumultiprocessing.Lock
depuis la version 2.6) pour simplifier l'implémentation du décorateur pour simplement:Quoi qu'il en soit, vous l'utilisez ensuite comme ceci:
Fondamentalement, il place simplement
lock.acquire()
/lock.release()
de chaque côté de l'appel de fonction.la source
J'utilise des décorateurs pour les paramètres de vérification de type qui sont passés à mes méthodes Python via certains RMI. Donc, au lieu de répéter le même comptage de paramètres, le mumbo-jumbo qui soulève des exceptions encore et encore.
Par exemple, au lieu de:
Je déclare simplement:
et
accepts()
fait tout le travail pour moi.la source
@accepts
PEP 318.isinstance()
fonction intégrée, comme cela se fait dans l' implémentation PEP 318 du décorateur. Puisque sonclassinfo
argument peut être d'un ou plusieurs types, son utilisation atténuerait également les objections (valides) de @ Gustavo6046. Python a également uneNumber
classe de base abstraite, donc des tests très génériques commeisinstance(42, numbers.Number)
sont possibles.Les décorateurs sont utilisés pour tout ce que vous souhaitez «envelopper» de manière transparente avec des fonctionnalités supplémentaires.
Django les utilise pour encapsuler la fonctionnalité "connexion requise" sur les fonctions d'affichage , ainsi que pour enregistrer les fonctions de filtre .
Vous pouvez utiliser des décorateurs de classe pour ajouter des journaux nommés aux classes .
Toute fonctionnalité suffisamment générique sur laquelle vous pouvez vous "accrocher" au comportement d'une classe ou d'une fonction existante est un jeu équitable pour la décoration.
Il y a aussi une discussion sur les cas d'utilisation sur le groupe de discussion Python-Dev pointé par PEP 318 - Décorateurs pour les fonctions et méthodes .
la source
Pour les tests noset, vous pouvez écrire un décorateur qui fournit une fonction ou une méthode de test unitaire avec plusieurs ensembles de paramètres:
la source
La bibliothèque Twisted utilise des décorateurs combinés à des générateurs pour donner l'illusion qu'une fonction asynchrone est synchrone. Par exemple:
En utilisant cela, le code qui aurait été décomposé en une tonne de petites fonctions de rappel peut être écrit tout naturellement en un seul bloc, ce qui le rend beaucoup plus facile à comprendre et à maintenir.
la source
Une utilisation évidente est bien sûr pour la journalisation:
la source
Je les utilise principalement pour le débogage (wrapper autour d'une fonction qui affiche ses arguments et ses résultats) et la vérification (par exemple pour vérifier si un argument est de type correct ou, dans le cas d'une application Web, si l'utilisateur a les privilèges suffisants pour appeler un particulier méthode).
la source
J'utilise le décorateur suivant pour créer une fonction threadsafe. Cela rend le code plus lisible. Elle est presque similaire à celle proposée par John Fouhy mais la différence est que l'on travaille sur une seule fonction et qu'il n'est pas nécessaire de créer explicitement un objet verrou.
la source
Les décorateurs sont utilisés soit pour définir les propriétés d'une fonction, soit comme passe-partout qui la modifie; il est possible mais contre-intuitif pour eux de retourner des fonctions complètement différentes. En regardant les autres réponses ici, il semble que l'une des utilisations les plus courantes consiste à limiter la portée d'un autre processus - que ce soit la journalisation, le profilage, les contrôles de sécurité, etc.
CherryPy utilise la répartition des objets pour faire correspondre les URL aux objets et, éventuellement, aux méthodes. Les décorateurs de ces méthodes indiquent si CherryPy est même autorisé à utiliser ces méthodes. Par exemple, adapté du tutoriel :
la source
Je les ai utilisés récemment, tout en travaillant sur une application Web de réseautage social. Pour la communauté / les groupes, j'étais censé donner l'autorisation d'adhésion pour créer une nouvelle discussion et répondre à un message que vous devez être membre de ce groupe particulier. J'ai donc écrit un décorateur
@membership_required
et je l'ai mis là où je le souhaitais à mon avis.la source
J'utilise ce décorateur pour fixer le paramètre
ceci écrit quand je refactorise certaines fonctions qui doivent passer l'argument "wanN" mais dans mes anciens codes, je ne passe que N ou 'N'
la source
Decorator peut être utilisé pour créer facilement des variables de méthode de fonction.
la source