À quoi sert le symbole «@ =» en Python?


173

je connais @ c'est pour les décorateurs, mais à quoi sert @=Python? Est-ce juste une réservation pour une idée future?

Ce n'est qu'une de mes nombreuses questions en lisant tokenizer.py.


1
Voir cset c553d8f72d65 ( miroir GitHub ... plus facile à lire ) dans le repo CPython.
— Nick T

SymbolHound est un moteur de recherche qui peut rechercher des symboles de ponctuation. Cependant, la recherche sur @ = python ne renvoie actuellement pas de résultats pertinents, car la documentation Python 3.5 contient '@' mais pas un exemple de '@ =' n'importe où. J'ai envoyé à SH un message pour aider à améliorer cela. La documentation Python pourrait également s'améliorer.
— smci

1
Combiné avec l' := opérateur morse de Python 3.8, vous obtenez ce que l'on appelle l' @:=opérateur rose épineuse. (Ou au Japon, il est connu sous le nom d'opérateur Elvis-morse.)
— Bob Stein

Réponses:


185

De la documentation :

L' @opérateur (at) est destiné à être utilisé pour la multiplication matricielle. Aucun type Python intégré n'implémente cet opérateur.

L' @opérateur a été introduit dans Python 3.5. @=est la multiplication matricielle suivie de l'affectation, comme vous vous en doutez. Ils correspondent à __matmul__, __rmatmul__ou __imatmul__similaires à comment +et +=correspondent à __add__, __radd__ou __iadd__.

L'opérateur et les raisons qui le sous-tendent sont discutés en détail dans la PEP 465 .


12
Cela explique pourquoi il se trouve dans la dernière version de tokenizer.py mais pas dans la documentation 3.4.
— Octavia Togami

10
Ceci est couvert dans la documentation de la version 3.5 - docs.python.org/3.5/reference/… et docs.python.org/3.5/reference/…
— jonrsharpe

Cela a-t-il un conflit avec les décorateurs Python? Cela n'est pas implémenté dans Python 2.n, non?
— frankliuao

4
Cela n'entre pas en conflit avec les décorateurs, car les décorateurs ne peuvent jamais être précédés d'une expression et les opérateurs binaires doivent toujours être précédés d'une expression.
— droite

58

@=et @sont de nouveaux opérateurs introduits dans Python 3.5 effectuant une multiplication matricielle . Ils visent à clarifier la confusion qui existait jusqu'à présent avec l'opérateur *qui était utilisé soit pour la multiplication élément par élément, soit pour la multiplication matricielle en fonction de la convention employée dans cette bibliothèque / code particulier. En conséquence, à l'avenir, l'opérateur *est destiné à être utilisé uniquement pour la multiplication élément par élément.

Comme expliqué dans PEP0465 , deux opérateurs ont été introduits:

  • Un nouvel opérateur binaire A @ B, utilisé de la même manière queA * B
  • Une version en place A @= B, utilisée de la même manière queA *= B

Multiplication matricielle vs multiplication par élément

Pour mettre rapidement en évidence la différence, pour deux matrices:

A = [[1, 2],    B = [[11, 12],
     [3, 4]]         [13, 14]]
  • La multiplication par élément donnera:

    A * B = [[1 * 11,   2 * 12], 
             [3 * 13,   4 * 14]]
  • La multiplication matricielle donnera:

    A @ B  =  [[1 * 11 + 2 * 13,   1 * 12 + 2 * 14],
               [3 * 11 + 4 * 13,   3 * 12 + 4 * 14]]

Utilisation dans Numpy

Jusqu'à présent, Numpy a utilisé la convention suivante:

L'introduction de l' @opérateur rend le code impliquant des multiplications matricielles beaucoup plus facile à lire. PEP0465 nous donne un exemple:

# Current implementation of matrix multiplications using dot function
S = np.dot((np.dot(H, beta) - r).T,
            np.dot(inv(np.dot(np.dot(H, V), H.T)), np.dot(H, beta) - r))

# Current implementation of matrix multiplications using dot method
S = (H.dot(beta) - r).T.dot(inv(H.dot(V).dot(H.T))).dot(H.dot(beta) - r)

# Using the @ operator instead
S = (H @ beta - r).T @ inv(H @ V @ H.T) @ (H @ beta - r)

De toute évidence, la dernière implémentation est beaucoup plus facile à lire et à interpréter comme une équation.


11
Juste pour clarifier: à partir de votre premier exemple, on pourrait penser que cela @a été mis en œuvre pour list, ce qui n'est pas le cas.
— Conchylicultor

1
@est associé à np.matmul, non np.dot. Les deux sont similaires mais pas identiques.
— Acumenus

@ABB, vous pourriez peut-être donner un exemple clarifiant la nuance et vous assurant que la réponse est alors complète?
— benjaminmgross

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.