语法
object.__rrshift__(self, other)
Python__rrshift__() 方法实现了 逆位右移操作反映,交换了操作数。因此,当你调用x >> y 时,Python 会尝试调用 [x.__rshift__(y)](https://blog.finxter.com/python-__rshift__/ "https://blog.finxter.com/python-__rshift__/").如果这个方法没有实现,Python 会尝试在右边的操作数上调用y.__rrshift__(x) ,如果这个方法也没有实现,它就会引发一个TypeError 。
__rrshift__() 方法在实践中经常被用来为一个尚未提供右移功能的类添加右移功能,该类不能被修改,比如一个列表或一个内置数据类型。通过为另一个操作数实现这个方法,你仍然可以为没有实现__rshift__() 的类使用右移功能。
我们称这种方法为*"* Dunder Method",即*"Double UnderscoreMethod"(也叫"Magic Method")*。
背景 位数右移法
Python的 ***位数右移***操作符x >> n 将整数x 的二进制表示向右移动了n 位。它在左边插入一个0 位,并删除最右边的位。
例如,如果你把二进制表示法0101 右移一个位置,你会得到0010 。从语义上讲,顺时针右移操作与进行整数除以2**n 是一样的。
print(8 << 1)
# 16
print(8 << 2)
# 32
print(-3 << 1)
# -6
Python __rshift__ 与 __rrshift__ 的比较
假设,你想对两个自定义对象x 和y 进行右移的计算。
print(x >> y)
Python 首先尝试调用左边对象的__rshift__() 方法x.__rshift__(y) 。但这可能因为两个原因而失败。
- 方法
x.__rshift__()首先没有实现,或者 - 方法
x.__rshift__()已经实现,但返回一个NotImplemented值,表明数据类型不兼容。
如果失败了,Python 试图通过调用y.__rrshift__() 对右操作数进行反向右移 来解决这个问题y 。并不是说这与左移不一样,它只是意味着右移操作是在第二个操作数上调用的y 。
如果实现了反向右移的方法,Python 知道它不会遇到非交换性操作的潜在问题。如果它只是执行y.__rshift__(x) 而不是x.__rshift__(y) ,结果就会是错误的,因为这个操作是非交换性的。这就是为什么需要y.__rrshift__(x) 。
因此,x.__rshift__(y) 和x.__rrshift__(y) 之间的区别是,前者计算x >> y 而后者计算y >> x - 两者都调用定义在对象x 上的各自方法。
你可以在这里看到这个效果,我们试图在左边的操作数x 上调用这个操作,但是由于它没有实现,Python 只是在右边的操作数y 上调用相反的操作。
class Data_1:
pass
class Data_2:
def __rrshift__(self, other):
return 'called reverse rshift'
x = Data_1()
y = Data_2()
print(x >> y)
# called reverse rshift