Prise en compte des décorateurs Python du type qui passe des variables

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)

Matériel de référence

À propos de Python Closure: pensez à la portée de la fonction et au fait que la fonction est un objet de première classe

Recommended Posts

Prise en compte des décorateurs Python du type qui passe des variables
[python] Vérifier la consommation de mémoire des variables
L'histoire de la manipulation des variables globales Python
[python] [meta] Le type de python est-il un type?
Pandas du débutant, par le débutant, pour le débutant [Python]
L'histoire selon laquelle le coût d'apprentissage de Python est faible
Traitement d'image? L'histoire du démarrage de Python pour
Code pour vérifier le fonctionnement de Python Matplot lib
[Python] Déterminez le type d'iris avec SVM
Comment trouver le coefficient de la courbe approximative passant par les sommets en Python
le zen de Python
[Python] Un programme qui compte le nombre de vallées
Programme Python qui recherche le même nom de fichier
L'attitude que les programmeurs devraient avoir (Le Zen de Python)
[Python] Un programme qui compare les positions des kangourous.
Un script python qui obtient le nombre de travaux pour une condition spécifiée sur Indeed.com
Vers la retraite de Python2
Vérifiez le fonctionnement de Python pour .NET dans chaque environnement
Python - Vérifiez le type de valeurs
Différent du type d'importation de python. Signification de depuis A import B
Notes diverses sur l'utilisation de python pour les projets
[Python] Les principales faiblesses et inconvénients de Google Colaboratory [Pour les débutants]
À propos des fonctionnalités de Python
Google recherche la chaîne sur la dernière ligne du fichier en Python
Script Python qui compare le contenu de deux répertoires
Le pouvoir des pandas: Python
Mémorandum de l'outil de gestion de paquets Python ez_setup
L'histoire selon laquelle la version de python 3.7.7 n'était pas adaptée à Heroku
Comment modifier le niveau de journalisation d'Azure SDK pour Python
Envelopper (partie de) la bibliothèque AtCoder en Cython pour une utilisation en Python
[Python] Organiser la structure de base de l'application Flask (Viser la dé-copie)
L'histoire de la création d'un pilote standard pour db avec python.
Une fonction qui mesure le temps de traitement d'une méthode en python
Vérification de la théorie selon laquelle "Python et Swift sont assez similaires"
python Remarque: map -faire la même chose pour chaque élément de la liste
[python] Une note que j'ai commencé à comprendre le comportement de matplotlib.pyplot
L'histoire de la création d'un module qui ignore le courrier avec python
[Python] Un programme qui fait pivoter le contenu de la liste vers la gauche
Initialisation de variables globales à l'aide de décorateurs Python
L'histoire de Python et l'histoire de NaN
Une bonne description des décorateurs Python
First Python 3 ~ Le début de la répétition ~
Python pour les super débutants Super débutants Python # dictionnaire type 1
Existence du point de vue de Python
pyenv-changer la version python de virtualenv
À propos du type de base de Go
Ceci et cela des propriétés python
[Python] Comprendre le potentiel_field_planning de Python Robotics
Revue des bases de Python (FizzBuzz)
Voir python pour la première fois
À quoi sert le trait de soulignement Python (_)?
Maîtriser le type avec Python [compatible Python 3.9]
Premiers pas avec python3