¿Para qué sirve el símbolo '@ =' en Python?

173

Sé que @es para decoradores, pero ¿ @=para qué sirve Python? ¿Es solo una reserva para alguna idea futura?

Esta es solo una de mis muchas preguntas mientras leo tokenizer.py.

Octavia Togami
fuente
1
Consulte cset c553d8f72d65 ( espejo de GitHub ... más fácil de leer ) en el repositorio de CPython.
Nick T
SymbolHound es un motor de búsqueda que puede buscar símbolos de puntuación. Sin embargo, la búsqueda en @ = python actualmente no devuelve resultados relevantes, porque la documentación de Python 3.5 contiene '@' pero no un ejemplo de '@ =' en ninguna parte. Envié a SH un mensaje para ayudar a mejorar eso. Python doc también podría mejorar.
smci
1
En combinación con el := operador de morsa de Python 3.8, obtienes lo que se conoce como el @:=operador de rosa espinosa. (O en Japón se le conoce como el operador de morsa de Elvis.)
Bob Stein

Respuestas:

185

De la documentación :

El @operador (at) está destinado a ser utilizado para la multiplicación de matrices. Ningún tipo de Python incorporado implementa este operador.

El @operador se introdujo en Python 3.5. @=es la multiplicación matricial seguida de la asignación, como era de esperar. Se asignan a __matmul__, __rmatmul__o __imatmul__similar a cómo +y se +=asignan a __add__, __radd__o __iadd__.

El operador y la justificación detrás de esto se discuten en detalle en PEP 465 .

pliegue derecho
fuente
12
Eso explica por qué está en la última versión de tokenizer.py pero no en los 3.4 documentos.
Octavia Togami
10
Esto está cubierto en los documentos de 3.5: docs.python.org/3.5/reference/… y docs.python.org/3.5/reference/…
jonrsharpe
¿Esto tiene conflicto con los decoradores de Python? Esto no está implementado en Python 2.n, ¿verdad?
frankliuao
44
Esto no entra en conflicto con los decoradores, porque los decoradores nunca pueden estar precedidos por una expresión, y los operadores binarios siempre deben estar precedidos por una expresión.
derecha el
58

@=y @son nuevos operadores introducidos en Python 3.5 que realizan la multiplicación de matrices . Su objetivo es aclarar la confusión que existía hasta ahora con el operador *que se usó para la multiplicación por elementos o la multiplicación de matrices, según la convención empleada en esa biblioteca / código en particular. Como resultado, en el futuro, el operador *debe usarse solo para la multiplicación por elementos.

Como se explica en PEP0465 , se presentaron dos operadores:

  • Un nuevo operador binario A @ B, utilizado de manera similar aA * B
  • Una versión in situ A @= B, utilizada de manera similar aA *= B

Multiplicación matricial vs Multiplicación por elementos

Para resaltar rápidamente la diferencia, para dos matrices:

A = [[1, 2],    B = [[11, 12],
     [3, 4]]         [13, 14]]
  • La multiplicación por elementos sabios producirá:

    A * B = [[1 * 11,   2 * 12], 
             [3 * 13,   4 * 14]]
  • La multiplicación de matrices producirá:

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

Uso en Numpy

Hasta ahora, Numpy usó la siguiente convención:

La introducción del @operador hace que el código que involucra multiplicaciones matriciales sea mucho más fácil de leer. PEP0465 nos da un ejemplo:

# 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)

Claramente, la última implementación es mucho más fácil de leer e interpretar como una ecuación.

Andrzej Pronobis
fuente
11
Solo para aclarar: desde su primer ejemplo, podríamos pensar que @se ha implementado para list, que no es el caso.
Conchylicultor
1
@está asociado con np.matmul, no np.dot. Los dos son similares pero no iguales.
Acumenus
@ABB, ¿tal vez podría proporcionar un ejemplo que aclare los matices y se asegure de que la respuesta esté completa?
benjaminmgross