你需要寫一個__eq__
功能來定義如何比較對象是否相等。如果你想排序,那麼你應該有一個__cmp__
函數,並且按照__cmp__
來實現__eq__
是最有意義的。
def __eq__(self, other):
return cmp(self, other) == 0
你或許應該還實現__hash__
,你絕對應該,如果你打算把你的對象爲一組或字典。對象的默認__hash__
是id(),它有效地使所有對象都是唯一的(即唯一性不基於對象內容)。
我爲一種類型的等價比較寫了一個基類/接口。你可能會發現它有用:
class Comparable(object):
def attrs(self):
raise Exception("Must be implemented in concrete sub-class!")
def __values(self):
return (getattr(self, attr) for attr in self.attrs())
def __hash__(self):
return reduce(lambda x, y: 37 * x + hash(y), self.__values(), 0)
def __cmp__(self, other):
for s, o in zip(self.__values(), other.__values()):
c = cmp(s, o)
if c:
return c
return 0
def __eq__(self, other):
return cmp(self, other) == 0
def __lt__(self, other):
return cmp(self, other) < 0
def __gt__(self, other):
return cmp(self, other) > 0
if __name__ == '__main__':
class Foo(Comparable):
def __init__(self, x, y):
self.x = x
self.y = y
def attrs(self):
return ('x', 'y')
def __str__(self):
return "Foo[%d,%d]" % (self.x, self.y)
def foo_iter(x):
for i in range(x):
for j in range(x):
yield Foo(i, j)
for a in foo_iter(4):
for b in foo_iter(4):
if a<b: print "%(a)s < %(b)s" % locals()
if a==b: print "%(a)s == %(b)s" % locals()
if a>b: print "%(a)s > %(b)s" % locals()
派生類必須實現attrs()
返回有助於其身份(即不變的屬性,使得它它是什麼)對象的屬性的元組或列表。最重要的是,代碼在存在多個屬性的情況下正確處理等同性,這是舊學校代碼,通常不正確。
我認爲他的問題是對象平等,而不是發現:) – extraneon 2010-04-01 08:39:47
OP有對象列表,而不是原子類型列表。如果你使用沒有定義'__hash__'的對象來嘗試你的代碼,它將不起作用,就像OP的代碼不能處理沒有定義'__eq__'或'__cmp__'的對象列表一樣。 – hughdbrown 2010-04-01 15:05:44