Python中的'@='符号是用来实现赋值运算符重载的。

233

我知道 @ 是用于装饰器的,但在Python中,@= 是什么意思?这只是为了保留一些未来的想法吗?

这只是我阅读 tokenizer.py 时遇到的众多问题之一。


1
请查看 CPython 仓库中的 cset c553d8f72d65GitHub 镜像更易读)。 - Nick T
SymbolHound是一个可以搜索标点符号的搜索引擎。然而,目前在SymbolHound上搜索@= python并不能返回相关结果,因为Python 3.5文档中包含“@”,但没有任何“@=”的示例。我已经向SH发送了一条消息以帮助改进这一点。Python文档也可以改进。 - smci
2
结合 Python 3.8 的 := 海象运算符,你就得到了所谓的 @:= 棘手的玫瑰运算符。(在日本则被称为 Elvis-海象运算符。) - Bob Stein
4个回答

263
根据文档增强赋值语句

@(at)运算符旨在用于矩阵乘法。没有内置的Python类型实现此操作符。

在Python 3.5中引入了@运算符。 @=是矩阵乘法后的赋值,正如您所期望的那样。它们映射到__matmul____rmatmul____imatmul__,类似于++=映射到__add____radd____iadd__
该运算符及其背后的原理在PEP 465中详细讨论。

15
这就解释了为什么它出现在最新版本的tokenizer.py中,但没有出现在3.4文档中。 - Octavia Togami
11
这个内容在 Python 3.5 的文档中有涵盖 - https://docs.python.org/3.5/reference/simple_stmts.html#augmented-assignment-statements 和 https://docs.python.org/3.5/reference/expressions.html#binary-arithmetic-operations。 - jonrsharpe
1
这会与Python装饰器产生冲突吗?这在Python 2.n中没有实现,对吧? - frankliuao
5
这并不会与装饰器冲突,因为装饰器永远不可能在表达式前出现,而二元运算符必须始终在表达式前出现。 - user1804599

120

@=@是Python 3.5中引入的新运算符,用于执行矩阵乘法。它们旨在澄清迄今为止存在的混淆,即运算符*根据特定库/代码所采用的约定被用于逐元素乘法或矩阵乘法。因此,将来,运算符*只应用于逐元素乘法。

PEP0465所述,引入了两个运算符:

  • 一个新的二进制运算符A @ B,与A * B类似
  • 一个原地版本A @= B,与A *= B类似

矩阵乘法与逐元素乘法

为了快速突出区别,对于两个矩阵:

A = [[1, 2],    B = [[11, 12],
     [3, 4]]         [13, 14]]
  • Element-wise multiplication will yield:

    A * B = [[1 * 11,   2 * 12], 
             [3 * 13,   4 * 14]]
    
  • Matrix multiplication will yield:

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

Numpy中的用法

到目前为止,Numpy使用以下约定:

引入@运算符可以使涉及矩阵乘法的代码更易读。 PEP0465给出了一个示例:

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

显然,最后一种实现更易于阅读和理解为一个方程式。

23
仅供澄清:从你的第一个例子中,我们可能会认为@已经被实现用于list,但事实并非如此。 - Conchylicultor
2
@np.matmul 相关联,而不是 np.dot。这两者相似但并不相同。 - Asclepius
1
@A-B-B,也许您可以提供一个例子来澄清细微差别,并确保答案完整? - benjaminmgross

10

0
Numpy 1.25将支持使用@=进行原地矩阵乘法操作。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接