[英]Python: Raise error when comparing objects of different type for equality
As far as I understand, in Python, comparing the instances of two different classes for equality, does:据我了解,在 Python 中,比较两个不同类的实例是否相等,确实:
__eq__
method of the first instance and return the result__eq__
方法并返回结果NotImplemented
, then evaluate the __eq__
method of the second instance and return the resultNotImplemented
,然后评估第二个实例的__eq__
方法并返回结果NotImplemented
, then compare for object identity and return the result (which is False)NotImplemented
,否则比较 object 身份并返回结果(为 False) I encountered multiple times situations where a raised Exception would have helped me to spot a bug in my code.我多次遇到引发异常的情况,这些情况可以帮助我发现代码中的错误。 Martijn Pieters has sketched in this post a way to do that, but also mentioned that it's unpythonic.
Martijn Pieters 在这篇文章中勾勒了一种方法来做到这一点,但也提到它是非 Python 的。
Besides being unpythonic, are there actual problems arising from this approach?除了不符合标准之外,这种方法是否存在实际问题?
Strictly speaking, it is, of course, "unpythonic" because Python encourages duck typing alongside strict subtyping.严格来说,它当然是“unpythonic”,因为 Python 鼓励鸭子类型和严格的子类型。 But I personally prefer strictly typed interfaces, so I throw
TypeError
s.但我个人更喜欢严格类型的接口,所以我抛出
TypeError
。 Never had any issues, but I can't difinitively say that you will never have any.从来没有任何问题,但我不能明确地说你永远不会有任何问题。
Theoretically, I can imagine it being a problem if you find yourself in need to use a mixed-type container like list[Optional[YourType]]
and then compare its elements, maybe indirectly, like in constructing set(your_mixed_list)
.从理论上讲,我可以想象如果您发现自己需要使用像
list[Optional[YourType]]
这样的混合类型容器然后比较它的元素,可能是间接的,就像在构造set(your_mixed_list)
时那样。
It would cause problems for dictionaries with mixed keys that have the same hash.这会导致具有相同 hash 的混合键的字典出现问题。 Dictionaries allow several keys to have the same hash, and then do an equality check to distinguish keys.
字典允许多个键具有相同的 hash,然后进行相等性检查以区分键。 See https://stackoverflow.com/a/9022835/1217284
见https://stackoverflow.com/a/9022835/1217284
The following script demonstrates this, it fails when the class Misbehaving1
is used:以下脚本演示了这一点,当使用 class
Misbehaving1
时它会失败:
#!/usr/bin/env python3
class Behaving1:
def __init__(self, value):
self.value = value
def __hash__(self):
return 7
class Behaving2:
def __init__(self, value):
self.value = value
def __hash__(self):
return 7
def __eq__(self, other):
if not (isinstance(other, type(self)) or isinstance(self, type(other))):
return NotImplemented
return self.value == other.value
class MisBehaving1:
def __init__(self, value):
self.value = value
def __hash__(self):
return 7
def __eq__(self, other):
if not (isinstance(other, type(self)) or isinstance(self, type(other))):
raise TypeError(f"Cannot compare {self} of type {type(self)} with {other} of type {type(other)}")
return self.value == other.value
d = {Behaving1(5): 'hello', Behaving2(4): 'world'}
print(d)
dd = {Behaving1(5): 'hello', MisBehaving1(4): 'world'}
print(dd)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.