Lors du développement avec Python, je pense qu'il existe de nombreux cas où vous souhaitez mettre un traitement commun avant et après une fonction. Dans ce cas, le décorateur (celui qui annote la ligne au-dessus de la fonction) est souvent utilisé. Dans cet article, j'aimerais examiner l'utilisation de base des décorateurs et les types de décorateurs qui peuvent transmettre des variables dans la seconde moitié.
Le décorateur le plus simple est l'implémentation suivante.
def decorator(func):
def decorated(*args, **kwargs):
print('Début décoré')
func(*args, **kwargs)
print('Fin décorée')
return decorated
Pour utiliser réellement ce décorateur, procédez comme suit.
@decorator
def sample(name):
print('{}Travaillé.'.format(name))
Lorsque cette fonction d'exemple décoré est exécutée, elle sera imprimée comme suit. Vous pouvez voir que le traitement est inséré avant et après la fonction exemple comme prévu.
Début décoré
échantillon a fonctionné.
Fin décorée
La raison pour laquelle cela fonctionne comme ça est que @ est du sucre de syntaxe C'est parce qu'il est en fait équivalent au code suivant.
def sample(name):
print('{}Travaillé.'.format(name))
# @Équivalent au décorateur
sample = decorator(sample)
C'est relativement facile à comprendre jusqu'à présent, mais je pense qu'il y a de nombreux cas où vous êtes bloqué lorsque vous essayez de comprendre le type de décorateur qui peut transmettre des variables.
def annotation(param):
print('début d'annotation')
def decorator(func):
print('Décorateur de départ')
print('param:{}'.format(param))
def decorated(*args, **kwargs):
print('Début décoré')
print('param:{}'.format(param))
func(*args, **kwargs)
print('Fin décorée')
print('décorateur terminé')
return decorated
print('fin d'annotation')
return decorator
Compte tenu du mouvement de la syntaxe sucre (@) mentionné précédemment, l'argument de la fonction de premier niveau (annotation) ne devrait-il pas être une fonction? C'est facile à penser, mais le code ci-dessous fonctionne très bien.
print('Définir une fonction annotée')
@annotation(param=999)
def sample(name):
print('{}Travaillé.'.format(name))
print('Exécuter la fonction annotée')
sample('sample')
La sortie d'impression est indiquée ci-dessous
Définir une fonction annotée
début d'annotation
fin d'annotation
Décorateur de départ
param:999
décorateur terminé
Exécuter la fonction annotée
Début décoré
param:999
échantillon a fonctionné.
Fin décorée
En regardant la sortie d'impression ci-dessus, parmi les fonctions de décorateur qui sont appelées après la fin de la fonction d'annotation Vous pouvez faire référence à param qui est l'argument de la fonction d'annotation. La raison de ce comportement est que les variables auxquelles la fonction peut faire référence sont déterminées lorsque la fonction est définie, de sorte que la fonction décoratrice définie dans la fonction d'annotation peut faire référence au paramètre qui est l'argument de la fonction d'annotation. Parce que.
De plus, compte tenu du contenu de la sortie d'impression, le sucre de syntaxe (@) du type de décorateur qui peut transmettre des variables est considéré comme équivalent à ce qui suit.
def sample(name):
print('{}Travaillé.'.format(name))
# @annotation(param=999)Équivalent à
sample = annotation(param=999)(sample)
Recommended Posts