学习Python的__rmul__()方法

501 阅读2分钟

句法

object.__rmul__(self, other)

Python__rmul__() 方法实现了反向乘法运算,即用反射的、交换的操作数进行乘法 。所以,当你调用x * y 时,Python 会尝试调用 [x.__mul__(y)](https://blog.finxter.com/python-__mul__/ "Python __mul__() Magic Method").只有当这个方法在左边的操作数上没有实现时,Python才会尝试在右边的操作数上调用__rmul__ ,如果这个方法也没有实现,它就会引发一个TypeError

我们称这种方法为*"* Dunder Method",即*"Double UnderscoreMethod"(也叫"Magic Method")*。

Python的__mul__与__rmul__比较

假设,你想在两个自定义对象xy 上计算* 运算。

print(x * y)

Python 首先尝试调用左边对象的__mul__() 方法x.__mul__(y) 。但这可能因为两个原因而失败。

  1. 方法x.__mul__() 首先没有实现,或者
  2. 方法x.__mul__() 已经实现,但是返回一个NotImplemented 值,表明数据类型不兼容。

如果失败了,Python 试图通过调用y.__rmul__() 对右操作数进行反向乘法 来解决这个问题y

如果反向乘法方法被实现,Python知道它不会遇到非交换性操作的潜在问题。如果它只是执行y.__mul__(x) 而不是x.__mul__(y) ,结果将是错误的,因为当定义为一个自定义操作时,该操作可能是非交替的。这就是为什么需要y.__rmul__(x)

因此,x.__mul__(y)x.__rmul__(y) 之间的区别是,前者计算x * y ,而后者计算y * x - 两者都调用各自定义在对象x 上的方法。

你可以在这里看到这个效果,我们试图在左边的操作数x 上调用这个操作,但是由于它没有实现,Python 只是在右边的操作数y 上调用相反的操作。

class Data_1:
    pass

class Data_2:
    def __rmul__(self, other):
        return 'called reverse *'


x = Data_1()
y = Data_2()

print(x * y)
# called reverse *