Reflected dunder 方法不适用于相同类型的实例
Reflected dunder method doesn't work for instances of the same type
这是一个小的重现 - class A 和 B 完全相同,为反射右移运算符实现了 dunder 方法。因此,x >> y
有望解析为 y.__rrshift__(x)
。
class A:
def __init__(self, x):
self.x = x
def __rrshift__(self, other):
return self.__class__(self.x + other.x)
class B:
def __init__(self, x):
self.x = x
def __rrshift__(self, other):
return self.__class__(self.x + other.x)
但是,dunder 方法不适用于相同 class 的实例。
A(1) >> A(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for >>: 'A' and 'A'
虽然它适用于来自不同 classes 的实例。
A(1) >> B(2)
<__main__.B object at 0x7f6ca8294f40>
这真是令人惊讶。并且似乎也是其他反映运算符的常见行为(例如 radd
)。这是行不通的原因吗?
同doc states一样,操作数不同类型时有效
These functions are only called if the left operand does not support the corresponding operation and the operands are of different types
看来你只需要 __rshift__
两个 类 (只有 A 对你的例子有效)
def __rshift__(self, other):
return self.__class__(self.x + other.x)
来自文档(Python 语言参考手册中的 3.3.8. Emulating numeric types 部分):
These functions are only called if the left operand does not support the corresponding operation [3] and the operands are of different types. [4]
其中 footnote 4 显示:
[4] For operands of the same type, it is assumed that if the non-reflected method – such as __add__()
– fails then the overall operation is not supported, which is why the reflected method is not called.
因此,无论喜欢与否,该行为都是有意为之并记录在案的。
这是一个小的重现 - class A 和 B 完全相同,为反射右移运算符实现了 dunder 方法。因此,x >> y
有望解析为 y.__rrshift__(x)
。
class A:
def __init__(self, x):
self.x = x
def __rrshift__(self, other):
return self.__class__(self.x + other.x)
class B:
def __init__(self, x):
self.x = x
def __rrshift__(self, other):
return self.__class__(self.x + other.x)
但是,dunder 方法不适用于相同 class 的实例。
A(1) >> A(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for >>: 'A' and 'A'
虽然它适用于来自不同 classes 的实例。
A(1) >> B(2)
<__main__.B object at 0x7f6ca8294f40>
这真是令人惊讶。并且似乎也是其他反映运算符的常见行为(例如 radd
)。这是行不通的原因吗?
同doc states一样,操作数不同类型时有效
These functions are only called if the left operand does not support the corresponding operation and the operands are of different types
看来你只需要 __rshift__
两个 类 (只有 A 对你的例子有效)
def __rshift__(self, other):
return self.__class__(self.x + other.x)
来自文档(Python 语言参考手册中的 3.3.8. Emulating numeric types 部分):
These functions are only called if the left operand does not support the corresponding operation [3] and the operands are of different types. [4]
其中 footnote 4 显示:
[4] For operands of the same type, it is assumed that if the non-reflected method – such as
__add__()
– fails then the overall operation is not supported, which is why the reflected method is not called.
因此,无论喜欢与否,该行为都是有意为之并记录在案的。