Classes, méthodes, itérateurs, constructeurs ... Lors de la programmation avec Python (mais sans s'y limiter), de nombreux termes et concepts techniques apparaissent. Ici, je vais vous expliquer les termes et usages que je n'entends plus, y compris la signification de Flame Learning et organiser mon esprit.
Le premier est decorator. (Il est indécis s'il faut faire la deuxième fois)
En un mot, c'est __ qui donne des fonctionnalités à la fonction __. Jetons un coup d'œil à un exemple de code de toute façon.
print_args_decorator.py
# -*- coding: utf-8 -*-
#Décorateur pour afficher les arguments
def print_args(func):
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
print('<args is ...>')
for arg in args:
print(arg)
for kwarg in kwargs:
print('{0}:{1}'.format(kwarg, kwargs[kwarg]))
return res
return wrapper
Décorons la fonction avec ce décorateur. Préparez la fonction.
seimei.py
# -*- coding: utf-8 -*-
def seimei(LastName, FirstName):
"""Afficher l'argument sous forme de nom"""
print('Nom complet:{0} {1}'.format(FirstName, LastName))
if __name__ == '__main__':
seimei(LastName='Jackson', FirstName='Michael')
Nom complet:Michael Jackson
Nous recevons le prénom et le nom de famille et les affichons comme nom. Et si vous y ajoutiez le décorateur que vous avez créé précédemment?
seimei_deco.py
# -*- coding: utf-8 -*-
from print_args_decorator import print_args
@print_args #Décorateur
def seimei(LastName, FirstName):
"""Afficher l'argument sous forme de nom"""
print('Nom complet:{0} {1}'.format(FirstName, LastName))
if __name__ == '__main__':
seimei(LastName='Jackson', FirstName='Michael')
Nom complet:Michael Jackson
<args is ...>
LastName:Jackson
FirstName:Michael
La valeur de l'argument est maintenant sortie avec la sortie de la fonction d'origine. En effet, la fonction qui renvoie le nom reçoit la fonction de sortie __arguments __. Je ne sais pas ce que c'est, mais ça semble pratique
Ce qui se passe à l'intérieur du décorateur est expliqué en détail dans les articles suivants.
Sur la base de cet article et de l'exemple de code ci-dessus, je vais vous expliquer le fonctionnement de base du décorateur. (Étant donné que ce qui précède touche également à la portée, qui est un concept important en programmation, il est recommandé aux débutants de Python de le lire.)
Tout d'abord, créez une pièce qui fonctionne comme décorateur. Dans l'exemple de code, il s'agit de la hiérarchie de
def print_args (func):
.
Cette fonction spécifie une fonction comme argument. De plus, si vous regardez l'instruction return dans la même hiérarchie, vous pouvez voir qu'elle renvoie une fonction appelée wrapper. Vous recevez une fonction, la traitez (en faites un wrapper) et la renvoyez.
Ensuite, créez une partie qui définit la fonction à donner. Dans l'exemple de code, il s'agit de la hiérarchie de def wrapper (* args, ** kwargs):
.
Dans cette fonction, la fonction reçue dans la couche supérieure est exécutée en premier. Je ne veux pas contraindre les arguments func, donc j'utilise \ * args, \ * \ * kwargs comme arguments. Puisque les décorateurs travaillent pour plusieurs fonctions et montrent leur vraie valeur, ils prennent souvent \ * args, \ * \ * kwargs comme arguments.
Après avoir exécuté func, j'imprime les arguments. Notez que \ * \ * kwargs stocke ses arguments sous forme de dict, donc les arguments sont dans l'ordre de tri conforme à dict, pas dans l'ordre dans lequel ils ont été créés lorsque la fonction a été créée.
Après avoir créé le décorateur, décorons la fonction.
Le décorateur est appelé avec une marque at juste avant la définition de la fonction. Dans l'exemple de code seimei_deco.py, le décorateur print_args est appelé par
@ print_args``` juste avant la fonction semei.
La fonction seimei "imprime maintenant ses arguments après avoir exécuté la fonction" en plus de son comportement d'origine.
Ajoutons un décorateur à une fonction différente de l'exemple ci-dessus. Il est bon que des décorateurs puissent être ajoutés à n'importe quelle fonction, donc je pense qu'il est préférable de les créer afin qu'ils puissent être utilisés à des fins générales, telles que la spécification de \ * args, \ * \ * kwargs comme arguments.
sum_deco.py
from print_args_decorator import print_args
@print_args
def sum_print_args(*args):
return sum(args)
if __name__ == '__main__':
sum_num = sum_print_args(1, 3)
print('SUM = {0}'.format(sum_num))
<args is ...>
1
3
SUM = 4
Si vous utilisez un décorateur pour générer une fonction, vous perdrez des informations telles que les chaînes de document.
Cela peut être évité en utilisant functools.wraps lors de la création du décorateur.
Vérifions la chaîne de document de
seimei_deeco.py``` créée plus tôt.
>>> from seimei_deco import seimei
>>> print(seimei.__doc__)
None
La chaîne du document sera None. Redéfinissons le décorateur en utilisant functools.wraps et vérifions la chaîne de document de la fonction générée.
seimei_deco_use_functools.py
# -*- coding: utf-8 -*-
#Décorateur pour afficher les arguments
def print_args(func):
import functools
@functools.wraps(func)
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
print('<args is ...>')
for arg in args:
print(arg)
for kwarg in kwargs:
print('{0}:{1}'.format(kwarg, kwargs[kwarg]))
return res
return wrapper
@print_args #Décorateur
def seimei(LastName, FirstName):
"""Afficher l'argument sous forme de nom"""
print('Nom complet:{0} {1}'.format(FirstName, LastName))
if __name__ == '__main__':
seimei(LastName='Jackson', FirstName='Michael')
>>> from seimei_deco_use_functools import seimei
>>> print(seimei.__doc__)
Afficher l'argument sous forme de nom
La chaîne de document de la fonction d'origine s'affiche. Le point ici est que functools.wraps lui-même est utilisé comme décorateur. (J'ai fait référence à cette page) Comme mentionné précédemment, les décorateurs doivent être créés afin qu'ils puissent être utilisés à des fins générales autant que possible, donc fondamentalement functools.wraps doit être utilisé.
Les décorateurs peuvent être attachés à n'importe quelle fonction. Par conséquent, il est efficace lors de l'exécution répétée de la même opération dans __ code __. Vous pouvez faire la même opération en créant une fonction au lieu d'un décorateur et en l'appelant un par un dans la définition de la fonction, mais en écrivant un peu à marquer une ligne avant la définition de la fonction, la lisibilité du code __ est améliorée. Peut être soulevé __. Ceci est très utile lorsque vous souhaitez collecter des journaux d'erreurs pour chaque méthode du module.
Aussi, quand je regarde le code du module, je vois parfois un décorateur appelé @property. Il s'agit d'une propriété de la fonction, mais je n'entrerai pas dans les détails ici. Veuillez vous reporter à cette page.
Recommended Posts