Je regarde du code Python qui a utilisé le @
symbole, mais je n'ai aucune idée de ce qu'il fait. Je ne sais pas non plus quoi rechercher car la recherche de documents Python ou Google ne renvoie pas de résultats pertinents lorsque le @
symbole est inclus.
python
syntax
python-decorators
AJ00200
la source
la source
Exemple
Cela montre que le
function
/method
/class
que vous définissez après un décorateur est simplement transmis comme unargument
aufunction
/method
immédiatement après le@
signe.Première observation
Le flacon microframework présente les décorateurs depuis le tout début dans le format suivant:
Cela se traduit à son tour par:
Réaliser cela m'a finalement permis de me sentir en paix avec Flask.
la source
app.route("/")
: cette fonction retourne une fonction, que vous invoquez avec votrehello()
comme argumentapp.route("/", hello)
immédiatement après la définitionhello
, ou même de définirhello
comme lambda dans les arguments deapp.route
? (Ce dernier exemple est commun avec leshttp.Server
routes Node.js et Express.)Cet extrait de code:
Est équivalent à ce code:
Dans la définition d'un décorateur, vous pouvez ajouter des éléments modifiés qui ne seraient pas retournés par une fonction normalement.
la source
Dans Python 3.5, vous pouvez surcharger
@
en tant qu'opérateur. Il est nommé comme__matmul__
, car il est conçu pour effectuer une multiplication matricielle, mais il peut être tout ce que vous voulez. Voir PEP465 pour plus de détails.Il s'agit d'une implémentation simple de la multiplication matricielle.
Ce code donne:
la source
@=
opérateur (sur place), qui est__imatmul__
.__add__
et__sub__
sont liés à + et - respectivement, mais je n'ai jamais entendu parler du@
signe auparavant. Y en a-t-il d'autres qui se cachent là-bas?Que fait le symbole «at» (@) en Python?
En bref, il est utilisé dans la syntaxe du décorateur et pour la multiplication matricielle.
Dans le contexte des décorateurs, cette syntaxe:
est équivalent à ceci:
Dans le contexte de la multiplication matricielle,
a @ b
invoquea.__matmul__(b)
- ce qui rend cette syntaxe:équivalent à
et
équivalent à
où
dot
est, par exemple, la fonction de multiplication matricielle numpy eta
etb
sont des matrices.Comment pourriez-vous découvrir cela par vous-même?
Si vous voulez avoir une vue assez complète de ce que fait un morceau particulier de syntaxe python, regardez directement le fichier de grammaire. Pour la branche Python 3:
Nous pouvons voir ici qu'il
@
est utilisé dans trois contextes:Syntaxe du décorateur:
Une recherche google pour "docs python décorateur" donne comme l'un des meilleurs résultats, la section "Instructions composées" de la "Référence du langage Python". En descendant jusqu'à la section sur les définitions des fonctions , que nous pouvons trouver en recherchant le mot "décorateur", nous voyons que ... il y a beaucoup à lire. Mais le mot "décorateur" est un lien vers le glossaire qui nous dit:
Donc on voit que
est sémantiquement identique à:
Ils ne sont pas exactement les mêmes car Python évalue l'expression foo (qui pourrait être une recherche en pointillés et un appel de fonction) avant bar avec la
@
syntaxe decorator ( ), mais évalue l'expression foo après bar dans l'autre cas.(Si cette différence fait une différence dans la signification de votre code, vous devriez reconsidérer ce que vous faites de votre vie, car ce serait pathologique.)
Décorateurs empilés
Si nous revenons à la documentation de la syntaxe de définition de fonction, nous voyons:
Ceci est une démonstration que nous pouvons appeler une fonction qui est d'abord un décorateur, ainsi que des décorateurs de pile. Les fonctions, en Python, sont des objets de première classe - ce qui signifie que vous pouvez passer une fonction comme argument à une autre fonction et renvoyer des fonctions. Les décorateurs font ces deux choses.
Si nous empilons les décorateurs, la fonction, telle que définie, est transmise en premier au décorateur immédiatement au-dessus, puis au suivant, et ainsi de suite.
Cela résume l'utilisation
@
dans le contexte des décorateurs.L'opérateur,
@
Dans la section d'analyse lexicale de la référence du langage, nous avons une section sur les opérateurs , qui inclut
@
, ce qui en fait également un opérateur:et dans la page suivante, le modèle de données, nous avons la section Émulation des types numériques ,
Et nous voyons que cela
__matmul__
correspond à@
. Si nous recherchons la documentation pour "matmul", nous obtenons un lien vers Quoi de neuf dans Python 3.5 avec "matmul" sous un titre "PEP 465 - Un opérateur d'infixe dédié pour la multiplication matricielle".(Alors maintenant, nous apprenons que
@=
c'est la version sur place). Il explique en outre:Bien que cet opérateur puisse être surchargé pour faire presque n'importe quoi, dans
numpy
, par exemple, nous utiliserions cette syntaxe pour calculer le produit intérieur et extérieur des tableaux et des matrices:Multiplication de matrice inplace:
@=
En recherchant l'utilisation antérieure, nous apprenons qu'il y a aussi la multiplication matricielle interne. Si nous essayons de l'utiliser, nous pouvons constater qu'il n'est pas encore implémenté pour numpy:
Quand il sera implémenté, je m'attendrais à ce que le résultat ressemble à ceci:
la source
@ symbol est un sucre syntaxique que python fournit pour utiliser
decorator
,pour paraphraser la question, c'est exactement ce que fait le décorateur en Python?
En termes simples,
decorator
vous pouvez modifier la définition d'une fonction donnée sans toucher son plus profond (c'est la fermeture).C'est le cas le plus important lorsque vous importez un merveilleux paquet de tiers. Vous pouvez le visualiser, vous pouvez l'utiliser, mais vous ne pouvez pas toucher son intérieur et son cœur.
Voici un exemple rapide,
supposons que je définisse une
read_a_book
fonction sur IpythonVous voyez, j'ai oublié d'y ajouter un nom.
Comment résoudre un tel problème? Bien sûr, je pourrais redéfinir la fonction comme:
Néanmoins, que se passe-t-il si je ne suis pas autorisé à manipuler la fonction d'origine ou s'il y a des milliers de fonctions à gérer.
Résoudre le problème en pensant différemment et définir une nouvelle_fonction
Ensuite, employez-le.
Tada, vous voyez, j'ai modifié
read_a_book
sans y toucher la fermeture intérieure. Rien ne m'arrête équipédecorator
.De quoi s'agit-il
@
@add_a_book
est une façon élégante et pratique de direread_a_book = add_a_book(read_a_book)
, c'est un sucre syntaxique, il n'y a rien de plus sophistiqué.la source
Si vous faites référence à du code dans un bloc-notes python qui utilise la bibliothèque Numpy , cela
@ operator
signifie la multiplication matricielle . Par exemple:la source
À partir de Python 3.5, le '@' est utilisé comme symbole d'infixe dédié pour MATRIX MULTIPLICATION (PEP 0465 - voir https://www.python.org/dev/peps/pep-0465/ )
la source
Des décorateurs ont été ajoutés en Python pour faciliter l' habillage des fonctions et des méthodes (une fonction qui reçoit une fonction et en renvoie une améliorée). Le cas d'utilisation d'origine était de pouvoir définir les méthodes en tant que méthodes de classe ou méthodes statiques en tête de leur définition. Sans la syntaxe du décorateur, il faudrait une définition plutôt clairsemée et répétitive:
Si la syntaxe du décorateur est utilisée dans le même but, le code est plus court et plus facile à comprendre:
Syntaxe générale et implémentations possibles
Le décorateur est généralement un objet nommé ( les expressions lambda ne sont pas autorisées ) qui accepte un seul argument lorsqu'il est appelé (ce sera la fonction décorée) et renvoie un autre objet appelable. "Appelable" est utilisé ici au lieu de "fonction" avec préméditation. Bien que les décorateurs soient souvent abordés dans le cadre des méthodes et des fonctions, ils ne se limitent pas à eux. En fait, tout ce qui est appelable (tout objet qui implémente la méthode _call__ est considéré comme appelable), peut être utilisé comme décorateur et souvent les objets retournés par eux ne sont pas de simples fonctions mais davantage d'instances de classes plus complexes implémentant leur propre méthode __call_.
La syntaxe du décorateur n'est tout simplement qu'un sucre syntaxique . Considérez l'utilisation du décorateur suivant:
Cela peut toujours être remplacé par un appel de décorateur explicite et une réaffectation de fonction:
Cependant, ce dernier est moins lisible et aussi très difficile à comprendre si plusieurs décorateurs sont utilisés sur une seule fonction. Les décorateurs peuvent être utilisés de différentes manières, comme indiqué ci-dessous:
En tant que fonction
Il existe de nombreuses façons d'écrire des décorateurs personnalisés, mais la manière la plus simple consiste à écrire une fonction qui renvoie une sous-fonction qui encapsule l'appel de fonction d'origine.
Les modèles génériques sont les suivants:
En tant que classe
Alors que les décorateurs peuvent presque toujours être implémentés à l'aide de fonctions, il existe certaines situations où l'utilisation de classes définies par l'utilisateur est une meilleure option. Cela est souvent vrai lorsque le décorateur a besoin d'un paramétrage complexe ou cela dépend d'un état spécifique.
Le modèle générique pour un décorateur non paramétré en tant que classe est le suivant:
Paramétrer les décorateurs
Dans le code réel, il est souvent nécessaire d'utiliser des décorateurs qui peuvent être paramétrés. Lorsque la fonction est utilisée comme décorateur, la solution est simple: un deuxième niveau d'emballage doit être utilisé. Voici un exemple simple du décorateur qui répète l'exécution d'une fonction décorée le nombre de fois spécifié chaque fois qu'elle est appelée:
Le décorateur ainsi défini peut accepter des paramètres:
Notez que même si le décorateur paramétré a des valeurs par défaut pour ses arguments, les parenthèses après son nom sont obligatoires. La façon correcte d'utiliser le décorateur précédent avec des arguments par défaut est la suivante:
Permet enfin de voir les décorateurs avec des propriétés.
Propriétés
Les propriétés fournissent un type de descripteur intégré qui sait comment lier un attribut à un ensemble de méthodes. Une propriété prend quatre arguments facultatifs: fget, fset, fdel et doc. Le dernier peut être fourni pour définir une docstring qui est liée à l'attribut comme s'il s'agissait d'une méthode. Voici un exemple de classe Rectangle qui peut être contrôlée soit par un accès direct aux attributs qui stockent deux points d'angle, soit en utilisant les propriétés width et height:
La meilleure syntaxe pour créer des propriétés est d'utiliser la propriété comme décorateur. Cela réduira le nombre de signatures de méthode à l' intérieur de la classe et rendra le code plus lisible et maintenable . Avec les décorateurs, la classe ci-dessus devient:
la source
Dire ce que les autres ont d'une manière différente: oui, c'est un décorateur.
En Python, c'est comme:
Cela peut être utilisé pour toutes sortes de choses utiles, rendues possibles parce que les fonctions sont des objets et juste des instructions nécessaires.
la source
@ Symbole est également utilisé pour les variables d'accès à l' intérieur d' un plydata / pandas géants dataframe requête,
pandas.DataFrame.query
. Exemple:la source
Cela indique que vous utilisez un décorateur. Voici l'exemple de Bruce Eckel de 2008.
la source