Comme mentionné par plusieurs experts ci-dessus, la fonction de décorateur (@grammar) est :
@foo
def bar():
...
équivaut à :
bar = foo(bar)
traduit en chinois est :
Utilisez la fonction représentée par @ comme argument pour appeler la fonction @, et attribuez la valeur au nom de la fonction @
représenté par la fonction
Parce que cette action est très similaire à la décoration (modification, agrandissement, ajustement, restriction...) originale bar, on l'appelle donc décorateur :
Par définition, un décorateur est une fonction qui prend une autre fonction et étend le comportement de cette dernière sans la modifier explicitement.
Bien que
soit considéré comme une décoration, le bar exécuté n'est plus la même personne que l'original bar renverra un tout nouvel objet, généralement une fonction, mais il est très probable que le foo soit une décoration. la chose renvoyée n'est rien du tout. Pas même une fonction :
def foo(func):
return None
@foo
def bar():
...
Dans l'exemple ci-dessus, foo est devenu un décorateur très étrange, car ce qu'il renvoie est None, qui non seulement n'a pas de décoration, mais détruit également la fonction
Votre foo n'a pas de déclaration return, ce qui signifie que foo reviendra None Ce que vous avez écrit est fondamentalement un destructeur (je plaisante). illusion. C'est parce qu'au moment où la syntaxe @ entre en jeu, la syntaxe print est exécutée
Mais vous pouvez essayer d'appeler func_a, vous constaterez qu'une erreur est générée, car func_a n'est pas du tout une fonction, et bien sûr l'effet que vous souhaitez obtenir ne peut pas être réutilisé
Les décorateurs ne doivent pas nécessairement utiliser des fonctions locales ou des fonctions imbriquées, mais nous laissons généralement le décorateur renvoyer une fonction. Je pense que c'est un point très important. Après tout, nous pensons tous intuitivement aux fonctions décorées.
Il existe des milliers de décorateurs, et certains peuvent en effet utiliser une seule couche d'imbrication, comme l'enregistrement de fonctions :
La raison est que cette action ne doit être traitée qu'une seule fois lors de la décoration. Vous ne voulez pas l'enregistrer à chaque fois que vous appelez la fonction. Tout ce dont nous avons besoin est la fonction d'origine.
Mais pour des actions comme imprimer le journal ou calculer le temps etc., nous devons toujours utiliser des techniques d'imbrication, car nous voulons imprimer et calculer à chaque fois que nous appelons une fonction. need est une nouvelle fonction. Cette fonction est créée par une fonction locale, qui produira inévitablement une cascade et une imbrication. Il existe également des décorateurs plus complexes avec des paramètres qui peuvent utiliser plus de deux niveaux d'imbrication
.
Résumé
Que vous souhaitiez emboîter ou non dépend du but recherché, mais n'oubliez pas de restituer la fonction après la décoration
Peut-être que vous ne comprenez pas ce que je veux dire. Mon idée est assez confuse. Ma question est de savoir pourquoi Python est conçu comme ça, car au début, je pensais qu'il était inutile d'imbriquer deux couches de fonctions et une. une couche de fonctions suffit. Imprimer un journal, l'heure, etc. Ce n'est pas la philosophie de python. J'y ai réfléchi pendant une nuit et je l'ai compris moi-même. Les amis dans le besoin peuvent y jeter un œil et s'émerveiller. à la merveille de ce modèle de conception. La méthode de raisonnement inverse utilisée consiste à clarifier les exigences de base puis à raisonner à rebours pour comprendre pourquoi chaque étape est écrite comme telle.
Comme mentionné par plusieurs experts ci-dessus, la fonction de décorateur (@grammar) est :
équivaut à :
traduit en chinois est :
Parce que cette action est très similaire à la décoration (modification, agrandissement, ajustement, restriction...) originale
Bien quebar
, on l'appelle donc décorateur :soit considéré comme une décoration, le
bar
exécuté n'est plus la même personne que l'originalbar
renverra un tout nouvel objet, généralement une fonction, mais il est très probable que lefoo
soit une décoration. la chose renvoyée n'est rien du tout. Pas même une fonction :Dans l'exemple ci-dessus,
foo
est devenu un décorateur très étrange, car ce qu'il renvoie estNone
, qui non seulement n'a pas de décoration, mais détruit également la fonctionRetour à l'exemple que vous avez donné au début :
Votre
foo
n'a pas de déclarationreturn
, ce qui signifie quefoo
reviendraNone
Ce que vous avez écrit est fondamentalement un destructeur (je plaisante). illusion. C'est parce qu'au moment où la syntaxe@
entre en jeu, la syntaxeprint
est exécutéeMais vous pouvez essayer d'appeler
func_a
, vous constaterez qu'une erreur est générée, carfunc_a
n'est pas du tout une fonction, et bien sûr l'effet que vous souhaitez obtenir ne peut pas être réutiliséLes décorateurs ne doivent pas nécessairement utiliser des fonctions locales ou des fonctions imbriquées, mais nous laissons généralement le décorateur renvoyer une fonction. Je pense que c'est un point très important. Après tout, nous pensons tous intuitivement aux fonctions décorées.
Il existe des milliers de décorateurs, et certains peuvent en effet utiliser une seule couche d'imbrication, comme l'enregistrement de fonctions :
La raison est que cette action ne doit être traitée qu'une seule fois lors de la décoration. Vous ne voulez pas l'enregistrer à chaque fois que vous appelez la fonction. Tout ce dont nous avons besoin est la fonction d'origine.
Mais pour des actions comme imprimer le journal ou calculer le temps etc., nous devons toujours utiliser des techniques d'imbrication, car nous voulons imprimer et calculer à chaque fois que nous appelons une fonction. need est une nouvelle fonction. Cette fonction est créée par une fonction locale, qui produira inévitablement une cascade et une imbrication. Il existe également des décorateurs plus complexes avec des paramètres qui peuvent utiliser plus de deux niveaux d'imbrication
.Résumé
Que vous souhaitiez emboîter ou non dépend du but recherché, mais n'oubliez pas de restituer la fonction après la décoration
Questions auxquelles j'ai répondu : Python-QA
Peut-être que vous ne comprenez pas ce que je veux dire. Mon idée est assez confuse. Ma question est de savoir pourquoi Python est conçu comme ça, car au début, je pensais qu'il était inutile d'imbriquer deux couches de fonctions et une. une couche de fonctions suffit. Imprimer un journal, l'heure, etc. Ce n'est pas la philosophie de python. J'y ai réfléchi pendant une nuit et je l'ai compris moi-même. Les amis dans le besoin peuvent y jeter un œil et s'émerveiller. à la merveille de ce modèle de conception. La méthode de raisonnement inverse utilisée consiste à clarifier les exigences de base puis à raisonner à rebours pour comprendre pourquoi chaque étape est écrite comme telle.
Le décorateur .
arrive dans la phase
定义
au lieu de la phase执行
La fonction décorateur
outer
doit renvoyer un被装饰的函数
, notez qu'elle doit renvoyer un定义
, pas调用
L'explication détaillée en bas est très bonne.
Beaucoup de personnes ont dû partager cela. J'ai également déjà écrit un blog. Si le sujet est intéressant, vous pouvez le consulter :
Explication détaillée des décorateurs Python
Équivalent à bar = foo(bar), comprenez simplement ceci
Le deuxième étage est à droite, la fonction est déjà exécutée lors de l'attribution d'une valeur à la barre.