Para que serve o símbolo '@ =' no Python?


173

Eu sei que @é para decoradores, mas o que é @=para Python? É apenas reserva para alguma idéia futura?

Esta é apenas uma das minhas muitas perguntas durante a leitura tokenizer.py.


1
Consulte cset c553d8f72d65 ( espelho GitHub ... mais fácil de ler ) no repositório CPython.
Nick T

O SymbolHound é um mecanismo de pesquisa que pode pesquisar símbolos de pontuação. No entanto, a pesquisa em @ = python atualmente não retorna resultados relevantes, porque a documentação do Python 3.5 contém '@', mas não um exemplo de '@ =' em qualquer lugar. Enviei SH uma mensagem para ajudar a melhorar isso. Doc Python poderia melhorar também.
SMCI

1
Combinado com o := operador de morsa do Python 3.8, você obtém o que é conhecido como o @:=operador de rosa espinhosa. (Ou no Japão é conhecido como o operador Elvis-walrus.)
Bob Stein

Respostas:


185

A partir da documentação :

O @operador (at) deve ser usado para multiplicação de matrizes. Nenhum tipo Python embutido implementa esse operador.

O @operador foi introduzido no Python 3.5. @=é a multiplicação da matriz seguida pela atribuição, como seria de esperar. Eles mapeiam para __matmul__, __rmatmul__ou __imatmul__similares a como +e +=mapeiam para __add__, __radd__ou __iadd__.

O operador e a lógica por trás dele são discutidos em detalhes no PEP 465 .


12
Isso explica por que está na versão mais recente do tokenizer.py, mas não na documentação do 3.4.
Octavia Togami


Isso tem conflito com os decoradores de Python? Isso não é implementado no Python 2.n, certo?
frankliuao

4
Isso não entra em conflito com os decoradores, porque os decoradores nunca podem ser precedidos por uma expressão e os operadores binários sempre devem ser precedidos por uma expressão.
rightfold 4/17

58

@=e @são novos operadores introduzidos no Python 3.5 executando a multiplicação de matrizes . Eles pretendem esclarecer a confusão que existia até agora com o operador *que foi usado para multiplicação por elementos ou por matriz, dependendo da convenção empregada nessa biblioteca / código específico. Como resultado, no futuro, o operador *deve ser usado apenas para multiplicação por elementos.

Conforme explicado no PEP0465 , dois operadores foram introduzidos:

  • Um novo operador binário A @ B, usado da mesma forma queA * B
  • Uma versão local A @= B, usada da mesma forma queA *= B

Multiplicação de matrizes vs Multiplicação por elementos

Para destacar rapidamente a diferença, para duas matrizes:

A = [[1, 2],    B = [[11, 12],
     [3, 4]]         [13, 14]]
  • A multiplicação por elementos produzirá:

    A * B = [[1 * 11,   2 * 12], 
             [3 * 13,   4 * 14]]
  • A multiplicação de matrizes produzirá:

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

Uso em Numpy

Até agora, a Numpy usou a seguinte convenção:

A introdução do @operador facilita a leitura do código que envolve multiplicações de matrizes. PEP0465 nos dá um exemplo:

# 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, a última implementação é muito mais fácil de ler e interpretar como uma equação.


11
Apenas para esclarecimento: do seu primeiro exemplo, poderíamos pensar que @isso foi implementado list, o que não é o caso.
Conchylicultor

1
@está associado a np.matmul, não np.dot. Os dois são semelhantes, mas não são os mesmos.
Acumenus

@ABB, talvez você possa fornecer um exemplo para esclarecer as nuances e garantir que a resposta esteja completa?
Benjaminmgross

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.