我创建了一个新的Python对象,如下所示
class Mylist(list):
def __cmp__(self,other):
if len(self)>len(other):
return 1
elif len(self)<len(other):
return -1
elif len(self)==len(other):
return 0
我的意图是,当比较两个Mylist
个对象时,具有大量项目的对象应该更高。
c=Mylist([4,5,6])
d=Mylist([1,2,3])
运行上述代码后,c
和d
应该相等(c==d
&lt; == True )。但我得到了
>>> c==d
False
>>> c>d
True
>>>
它们与列表对象本身进行比较。我做错了什么?
答案 0 :(得分:2)
您需要实现函数__eq__
。
class Mylist(list):
def __cmp__(self,other):
if len(self)>len(other):
return 1
elif len(self)<len(other):
return -1
elif len(self)==len(other):
return 0
def __eq__(self, other):
return len(self)==len(other)
更新:(之前的代码无法完全按照评论中的说明运作)
尽管@tobias_k的答案解释得更好,但如果你坚持的话,可以通过Python 2中的__cmp__
函数来解决。您可以通过删除其他比较函数(le,lt,ge,...)来启用:
class Mylist(list):
def __cmp__(self,other):
if len(self)>len(other):
return 1
elif len(self)<len(other):
return -1
elif len(self)==len(other):
return 0
def __eq__(self, other):
return len(self)==len(other)
@property
def __lt__(self, other): raise AttributeError()
@property
def __le__(self, other): raise AttributeError()
@property
def __ne__(self, other): raise AttributeError()
@property
def __gt__(self, other): raise AttributeError()
@property
def __ge__(self, other): raise AttributeError()
答案 1 :(得分:1)
问题似乎是list
实现了所有rich comparison operators,而__cmp__
将实现only be called if those are not defined。因此,似乎你必须覆盖所有这些:
class Mylist(list):
def __lt__(self, other): return cmp(self, other) < 0
def __le__(self, other): return cmp(self, other) <= 0
def __eq__(self, other): return cmp(self, other) == 0
def __ne__(self, other): return cmp(self, other) != 0
def __gt__(self, other): return cmp(self, other) > 0
def __ge__(self, other): return cmp(self, other) >= 0
def __cmp__(self, other): return cmp(len(self), len(other))
顺便说一下,看来__cmp__
完全在Python 3中删除了。上面的内容适用于Python 2.x,但为了兼容性,你应该更喜欢这样做
def __lt__(self, other): return len(self) < len(other)
另请参阅这两个related questions。请注意,虽然在Python 3中实现__eq__
和__lt__
并且让Python推断其余部分就足够了,但在这种情况下这不起作用,因为list
已经实现了所有这些,所以你必须全部覆盖它们。