Maison  >  Article  >  développement back-end  >  Définition du décorateur Python et exemples d'application expliqués

Définition du décorateur Python et exemples d'application expliqués

乌拉乌拉~
乌拉乌拉~original
2018-08-22 16:17:371092parcourir

Dans l'article suivant, nous découvrirons ce que sont les décorateurs python. Découvrez les décorateurs Python et leur utilisation. Bon, sans plus tarder, commençons par le prochain article.

python decorator

En bref, pythondecorator est une fonction utilisée pour étendre les fonctionnalités de la fonction d'origine. Cette fonction est spéciale La différence. est que sa valeur de retour est aussi une fonction. L'avantage d'utiliser des décorateurs python est d'ajouter de nouvelles fonctions à la fonction sans changer le code de la fonction d'origine.

Puisqu'une fonction est également un objet et que les objets de fonction peuvent être affectés à des variables, la fonction peut également être appelée via des variables.

>>> def now():
...     print('2015-3-25')
...
>>> f = now
>>> f()
2015-3-25

L'objet fonction a un attribut __name__, qui peut obtenir le nom de la fonction :

>>> now.__name__
'now'
>>> f.__name__
'now'

Maintenant, supposons que nous souhaitions améliorer la fonctionnalité de la fonction now() , par exemple, dans Imprimer automatiquement les journaux avant et après les appels de fonction, mais vous ne souhaitez pas modifier la définition de la fonction now(). Cette méthode d'ajout dynamique de fonctions pendant l'exécution du code est appelée « Décorateur ».

Essentiellement, un décorateur est une fonction d'ordre supérieur qui renvoie une fonction. Par conséquent, nous devons définir un décorateur capable d'imprimer des logs, qui peut être défini comme suit :

def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)   
   return wrapper

Observez le log ci-dessus, car c'est un décorateur, il accepte une fonction comme paramètre et renvoie un fonction. Nous devons utiliser la syntaxe @ de Python pour placer le décorateur à la définition de la fonction :

@log
def now():
    print('2015-3-25')

L'appel de la fonction now() exécutera non seulement la fonction now() elle-même, mais aussi avant d'exécuter la fonction now () fonction Imprimer une ligne de log :

>>> now()
call now():
2015-3-25

Mettre @log à la définition de la fonction now(), ce qui équivaut à exécuter l'instruction :

now = log(now)

Depuis log( ) est un décorateur, renvoie une fonction A, donc la fonction originale now() existe toujours, mais maintenant la variable now du même nom pointe vers la nouvelle fonction, donc appeler now() exécutera la nouvelle fonction, c'est-à-dire le wrapper () renvoyée dans la fonction log().

La définition du paramètre de la fonction wrapper() est (*args, **kw Par conséquent, la fonction wrapper() peut accepter des appels avec n'importe quel paramètre. Dans la fonction wrapper(), le journal est imprimé en premier, puis la fonction d'origine est appelée.

Si le décorateur lui-même doit passer des paramètres, alors vous devez écrire une fonction d'ordre supérieur qui renvoie le décorateur, ce qui sera plus compliqué à écrire. Par exemple, pour personnaliser le texte du log :

def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))          
          return func(*args, **kw)  
        return wrapper  
     return decorator

L'utilisation de ce décorateur imbriqué à 3 couches est la suivante :

@log('execute')
 def now():
   print('2015-3-25')

Le résultat de l'exécution est le suivant :

>>> now()
execute now():
2015-3-25

Par rapport à deux niveaux de décorateurs imbriqués, l'effet de trois niveaux d'imbrication est le suivant :

>>> now = log('execute')(now)

Analysons d'abord l'instruction ci-dessus, log('execute') est exécuté et la fonction décoratrice est renvoyée, puis appelez la fonction renvoyée, le paramètre est la fonction now et la valeur de retour est enfin la fonction wrapper.

Il n'y a aucun problème avec les deux définitions de décorateur ci-dessus, mais il reste encore une dernière étape. Parce que nous avons dit que les fonctions sont aussi des objets, elles ont des attributs tels que __name__, mais si vous regardez les fonctions décorées avec des décorateurs, leur __name__ est passé de l'original « maintenant » à « wrapper » :

>>> now.__name__'
wrapper'

Étant donné que le nom de la fonction wrapper() renvoyée est 'wrapper', vous devez copier le __name__ et les autres attributs de la fonction d'origine dans la fonction wrapper(). Sinon, l'exécution de certains codes qui s'appuient sur les signatures de fonction le sera. échouer. Quelque chose s'est mal passé.

Il n'est pas nécessaire d'écrire du code comme wrapper.__name__ = func.__name__. Le functools.wraps intégré de Python fait cela. Par conséquent, un décorateur complet est écrit comme suit :

import functools
   def log(func):
   @functools.wraps(func)
     def wrapper(*args, **kw)
       print('call %s():' % func.__name__)      
     return func(*args, **kw)    
   return wrapper
Ou pour un décorateur avec paramètres :

import functoolsdef log(text):
    def decorator(func):
      @functools.wraps(func)
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))        
          return func(*args, **kw)    
         return wrapper  
       return decorator
import functools consiste à importer le module functools. Le concept de modules sera expliqué plus tard. Maintenant, n'oubliez pas d'ajouter @functools.wraps(func) avant de définir wrapper().

Ce qui précède est tout le contenu de cet article. Cet article présente principalement les connaissances liées au

décorateur python. J'espère que vous pourrez utiliser les informations pour comprendre le contenu ci-dessus. J'espère que ce que j'ai décrit dans cet article vous sera utile et vous facilitera l'apprentissage de Python.

Pour plus de connaissances connexes, veuillez visiter la colonne

Tutoriel Python du site Web php chinois.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn