Python集合如何检查两个对象是否相等?对象需要定义哪些方法来进行自定义?
我需要在Python中创建一个“容器”对象或类,用来记录我定义的其他对象。这个容器有一个要求,就是如果两个对象被认为是相同的,就要去掉其中一个(任意一个)。我最开始的想法是用一个 set([])
来作为这个容器,以满足这个要求。
但是,发现这个集合并不会自动去掉两个相同的对象实例。我需要定义什么才能实现这个功能呢?
下面是Python代码。
class Item(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
def __repr__(self):
return "Item(%s, %s)" % (self.foo, self.bar)
def __eq__(self, other):
if isinstance(other, Item):
return ((self.foo == other.foo) and (self.bar == other.bar))
else:
return False
def __ne__(self, other):
return (not self.__eq__(other))
解释器
>>> set([Item(1,2), Item(1,2)])
set([Item(1, 2), Item(1, 2)])
很明显,__eq__()
方法是通过 x == y
被调用的,但集合并没有调用这个方法。那么它调用的是什么呢?我还需要定义什么其他的方法呢?
注意:这些 Item
对象必须是可变的,可以改变,所以我不能提供一个 __hash__()
方法。如果这是唯一的解决办法,那我就会考虑使用不可变的 Item
对象。
2 个回答
81
是的,你需要一个 __hash__()
方法,还有你已经提供的比较操作符。
class Item(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
def __repr__(self):
return "Item(%s, %s)" % (self.foo, self.bar)
def __eq__(self, other):
if isinstance(other, Item):
return ((self.foo == other.foo) and (self.bar == other.bar))
else:
return False
def __ne__(self, other):
return (not self.__eq__(other))
def __hash__(self):
return hash(self.__repr__())
40
我担心你需要提供一个 __hash__()
方法。不过你可以写这个方法,让它不依赖于你 Item
类中那些可变的属性。