À 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.

Octavia Togami
la source
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 .

à droite
la source
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.

Andrzej Pronobis
la source
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