我正在探索python。
如果现在已经从答案中解脱出来,那么当我使用*
时,
a = [1, 2, 3]
b = a*2
c = 2*a
调用 a.__mul__()
来计算b
,a.__rmul__()
来计算c
(这更昂贵,因为试图将整数称为第一个:))
所以,一般来说:
我怎么能看到为某些快捷运算符(如 *
、and
或 +=
、
Python 语言参考 3.3.7:模拟数值类型说明了__rXXX__
魔术方法:
调用这些方法来实现二进制算术运算(
+
、-
、*
、/
、//
、%
、divmod()
、pow()
、**
、<<
、>>
、&
、^
、|
)和 r 偏转(交换)操作数。仅当左操作数不支持相应的操作并且操作数类型不同时,才会调用这些函数。例如,要计算表达式x - y
,其中y
是具有__rsub__()
方法的类的实例,如果x.__sub__(y)
返回NotImplemented
,则调用y.__rsub__(x)
。
因此,对于您的情况:首先对于a * b
Python 尝试调用 a.__mul__(b)
.如果此方法不存在或返回NotImplemented
,Python 调用 b.__rmul__(a)
。如果返回一个不NotImplemented
的值,那将是乘法的结果。
这样,只有a
或b
中的一个需要支持乘以另一个。
在这种将列表(或任何序列)乘以整数的特定情况下,执行[1, 2, 3] * 2
比执行2 * [1, 2, 3]
效率略高;两者都给出相同的结果,但[1, 2, 3] * 2
调用首先list.__mul__
:
>>> [1,2,3].__mul__(2)
[1, 2, 3, 1, 2, 3]
后者首先调用int.__mul__
,给定一个list
,返回NotImplemented
:
>>> (2).__mul__([1,2,3])
NotImplemented
然后 Python 继续调用 [1, 2, 3].__rmul__(2)
:
>>> [1,2,3].__rmul__(2)
[1, 2, 3, 1, 2, 3]
当然,乘法通常不是可交换的;想想矩阵乘
当对象本身位于左侧时调用__mul__
,当对象本身位于右侧时调用__rmul__
。对于这些特定的对象,2*a
具有与a*2
相同的结果,因为这种乘法是可交换的,所以它得出的是同一件事,所以两个文档字符串都是正确的。