学习Python的__rsub__()方法

622 阅读2分钟

句法

object.__rsub__(self, other)

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

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

Python的__sub__与__rsub__

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

print(x - y)

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

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

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

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

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

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

class Data_1:
    pass

class Data_2:
    def __rsub__(self, other):
        return 'called reverse -'


x = Data_1()
y = Data_2()

print(x - y)
# called reverse -