class Inner():
def __init__(self, x):
self.x = x
def __eq__(self, other):
if isinstance(other, Inner):
return self.x == other.x
else:
raise TypeError("Incorrect type to compare")
class Outer():
def __init__(self, y):
self.y = Inner(y)
def __eq__(self, other):
if isinstance(other, Outer):
return self.y == other.y
elif isinstance(other, Inner):
return self.y == other
else:
raise TypeError("Incorrect type to compare")
if __name__ == "__main__":
a = Outer(1)
b = Inner(1)
print(a == b) # ok no problem
print(b == a) # This will raise a type error
在示例中,我有内部和外部类。我无法控制内部工具只是想模拟这种情况。我只能控制Outer的行为。我希望外部实例能够与内部实例进行比较(而不仅仅是相等)。使用给定的实现只有第一个比较有效,因为调用Outer的__eq__
方法允许与外部和内部实例进行比较,但第二个调用Inner的__eq__
,这将不允许与外部进行比较 - 哎它不知道外面存在为什么要花时间去实现它。
有没有办法让第二种类型的比较工作,类似于__radd__
和类似的功能。
我知道,例如在C ++中,你使用内联运算符定义解决了这个问题,但我们在Python中没有这样做。
答案 0 :(得分:2)
不要过分夸大其词:Inner.__eq__
已被破坏。至少,它应该return NotImplemented
,而不是抛出一个错误,这将允许Python尝试反向比较:
当返回
NotImplemented
时,解释器将尝试 反映其他类型的操作,或其他一些后备, 取决于运营商。如果所有尝试的操作都返回NotImplemented
,口译员会提出适当的例外。
更好的是它会使用"duck typing",而不是坚持一个特定的类(除非类,而不是它的接口,是比较中明确重要的部分):
def __eq__(self, other):
try:
return self.x == other.x
except AttributeError:
return NotImplemented
但是,正如您所说无法控制这一点,您必须手动实现类似的功能,例如:
def compare(a, b):
"""'Safe' comparison between two objects."""
try:
return a == b
except TypeError:
return b == a
因为Python's data model中没有__req__
这样的内容。