句法
object.__rand__(self, other)
Python__rand__() 方法实现了反向的Bitwise AND *操作,其操作数被反射、交换。因此,当你调用x * y ,Python会尝试调用 [x.__and__(y)](https://blog.finxter.com/python-__and__/ "Python __and__() Magic Method").如果这个方法没有实现,Python 会尝试在右边的操作数上调用__rand__ ,如果这个方法也没有实现,它会引发一个TypeError 。
我们称这种方法为*"* Dunder Method",即*"Double UnderscoreMethod"(也叫"Magic Method")*。
背景 位数与 &
Python的位数与运算符对整数x 和y 的二进制表示中的每个位进行逻辑与运算。
因此,如果同一位置的两个输入位都是1,每个输出位就是1,否则就是0。
例如,整数表达式4&3被翻译成二进制的0100&0011,结果是0000,因为所有四个输入位的位置都不同。
在这个例子中,你将 位数与 操作符到两个整数 32 和 16。
>>> 32 & 16
0
表达式32 & 16 对位表示法"010000" (十进制 32) 和"001000" (十进制 16) 进行操作,并执行 位数与.由于所有第i个位的位置都不同,结果是0。
第一个操作数x | 1 | 0 | 0 | 0 | 0 | 0 |
第二个操作数y | 0 | 1 | 0 | 0 | 0 | 0 |
x & y | 0 | 0 | 0 | 0 | 0 | 0 |
Python __and__ 与 __rand__ 的比较
假设,你想对两个自定义对象x 和y 进行& 计算。
print(x & y)
Python 首先尝试调用左边对象的__and__() 方法x.__and__(y) 。但这可能因为两个原因而失败。
- 方法
x.__and__()首先没有实现,或者 - 方法
x.__and__()已经实现,但是返回一个NotImplemented值,表明数据类型不兼容。
如果失败了,Python 试图通过在右操作数上调用y.__rand__() 的反向位法和 方法来解决这个问题y 。
如果反向位数和方法被实现,Python 知道它不会遇到非交换性操作的潜在问题。如果它只是执行y.__and__(x) 而不是x.__and__(y) ,结果将是错误的,因为当定义为自定义操作时,该操作可能是非交换性的。这就是为什么需要y.__rand__(x) 。
因此,x.__and__(y) 和x.__rand__(y) 之间的区别是,前者计算x & y ,而后者计算y & x - 都是调用定义在对象x 上的各自方法。
你可以在这里看到这个效果,我们试图在左边的操作数x 上调用这个操作,但是由于它没有实现,Python 只是在右边的操作数y 上调用相反的操作。
class Data_1:
pass
class Data_2:
def __rand__(self, other):
return 'called reverse bitwise AND'
x = Data_1()
y = Data_2()
print(x & y)
# called reverse bitwise XOR