我想做类似的事情:
class Thing(object):
self.mySet = Set()
self.mySet.add(Cell((0,0),25))
self.mySet.add(Cell((0,1),50))
self.mySet.add(Cell((0,2),75))
def ClaimCell(self, cell):
self.mySet.remove(cell)
class Cell(object):
def __init__(self,index,value):
self.index = index
self.value = value
但实质上,我希望能够基于Cell
的成员而不是实例本身进行查找。我希望能够测试传入的cell.index
是否与cell.index
中的self.mySet
匹配。我可以为此覆盖__cmp__
类型的方法吗?或者我被迫循环遍历Set,每次检查索引,然后手动删除相应的条目?
答案 0 :(得分:1)
在Python中,两个相似的对象并不相同。引用__hash__
,
如果某个类未定义
__cmp__()
或__eq__()
方法,则不应定义__hash__()
操作;如果它定义__cmp__()
或__eq__()
但不定义__hash__()
,则其实例将无法在散列集合中使用。如果一个类定义了可变对象并实现了__cmp__()
或__eq__()
方法,那么它不应该实现__hash__()
,因为hashable collection实现要求对象的哈希值是不可变的(如果对象的哈希值)更改,它将在错误的哈希桶中。)默认情况下,用户定义的类具有
__cmp__()
和__hash__()
方法;与他们一起,所有对象比较不等(除了他们自己)和x.__hash__()
返回从id(x)
派生的结果。
因此,如果您想要将两个对象视为相同,则需要覆盖__eq__
和__hash__
方法,例如
class Cell(object):
def __init__(self, index, value):
self.index = index
self.value = value
def __hash__(self):
return hash(self.index)
def __eq__(self, other):
return other.index == self.index
def __repr__(self):
return "Index: {}, Value: {}".format(self.index, self.value)
由于您要根据index
进行比较,因此只会对index
进行哈希处理,并在覆盖的__hash__
方法中返回。
如果两个哈希值相等,那么Python将通过内部调用__eq__
方法检查两个对象是否相同。因此,我们也覆盖了该方法,只返回比较两个对象index
的结果
def __eq__(self, other):
return other.index == self.index
我们已经覆盖了__repr__
,只是为了在打印时看到实际的元素。
现在,当你做这样的事情时
class Thing(object):
def __init__(self):
self.mySet = set()
self.mySet.add(Cell((0, 0), 25))
self.mySet.add(Cell((0, 1), 50))
self.mySet.add(Cell((0, 2), 75))
def ClaimCell(self, cell):
self.mySet.remove(cell)
print(self.mySet)
Thing().ClaimCell(Cell((0, 1), 99))
你会得到
set([Index: (0, 0), Value: 25, Index: (0, 2), Value: 75])
请注意,我们尝试删除的Cell
对象的值为99
,因为我们只考虑index
进行对象识别,因此删除了Cell
index (0, 1)
。