学习Python的 __rxor__() 方法

395 阅读2分钟

句法

object.__rxor__(self, other)

Python__rxor__() 方法实现了反向的Bitwise XOR ^操作,其操作数被反射、交换。因此,当你调用x ^ y 时,Python 会尝试调用 [x.__xor__(y)](https://blog.finxter.com/python-__xor__-magic-method/ "Python __xor__() Magic Method").如果这个方法没有实现,Python 会尝试在右边的操作数上调用__rxor__ ,如果这个方法也没有实现,它会引发一个TypeError

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

背景 位数XOR ^

Python的位数XOR操作符在整数xy 的二进制表示上的每个位上执行逻辑XOR

当且仅当 同一位置上的两个输入位中有一个是1时,每个输出位才会被评估为1。

例如,整数表达式4 ^ 3 被翻译成二进制运算0100 ^ 0011 ,结果是0111 ,因为最后三个位置正好有一个比特是1。

在这个例子中,你将 位数XOR 操作符到两个整数 32 和 16。

>>> 32 ^ 16
48

表达式32 ^ 16 对位表示"0100000" (十进制32)和"0010000" (十进制16)进行操作,并执行 位数XOR结果是二进制"0110000" (十进制48)。

第一个操作数x100000
第二个操作数y010000
x ^ y110000

Python __xor__ 与 __rxor__ 的比较

假设,你想对两个自定义对象xy 进行^ 的计算。

print(x ^ y)

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

  1. 该方法x.__xor__() 首先没有实现,或者
  2. 该方法 x.__x`or`__()实现了,但返回一个NotImplemented ,表明数据类型不兼容。

如果失败了,Python 试图通过调用右操作数的反向位法 XORy.__rxor__() 来解决这个问题y

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

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

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

class Data_1:
    pass

class Data_2:
    def __rxor__(self, other):
        return 'called reverse bitwise XOR'


x = Data_1()
y = Data_2()

print(x ^ y)
# called reverse bitwise XOR