实现一个带有重写__cmp__函数的列表包装器
实现一个带有重写__cmp__函数的列表包装器
我创建了一个新的Python对象,代码如下:\n
class Mylist(list): def __cmp__(self,other): if len(self)>len(other): return 1 elif len(self)\n我的意图是,当比较两个`Mylist`对象时,拥有更多项目的对象应该更大。\n
c=Mylist([4,5,6]) d=Mylist([1,2,3])\n运行上述代码后,`c`和`d`应该相等(`c==d` <== True)。但是我得到的结果是:\n[apcode language="python"]
>>>> c==d False >>>> c>d True >>>[/apcode]\n它们被比较得像是`list`对象本身。我做错了什么?
问题的出现原因是因为Python中的列表(list)类已经实现了所有的比较运算符,所以当定义了__cmp__函数时,它只会在其他比较运算符未定义时才会被调用。因此,需要重写所有比较运算符。
解决方法是创建一个继承自列表类的自定义类,并重写所有比较运算符。下面是一个示例代码:
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))
另外需要注意的是,Python 3中已经完全删除了__cmp__函数。上述代码适用于Python 2.x版本。为了保持兼容性,可以使用以下代码替代:
def __lt__(self, other): return len(self) < len(other)
还可以参考这两个相关问题的链接:链接1和链接2。需要注意的是,在Python 3中,只需要实现__eq__和__lt__函数,Python会自动推断出其他比较运算符的实现。但在这个问题中,因为列表类已经实现了所有比较运算符,所以需要重写所有比较运算符。
问题的原因是需要实现一个列表包装器,并重写了 __cmp__ 函数。解决方法是实现 __eq__ 函数来代替 __cmp__ 函数。
代码示例中的 Mylist 类继承自内置的 list 类,并覆盖了 __cmp__ 函数和 __eq__ 函数。在 __cmp__ 函数中,通过比较两个列表的长度来确定它们的大小关系。在 __eq__ 函数中,通过比较两个列表的长度来确定它们是否相等。
然而,这段代码在某些情况下并不完美地工作。为了解决这个问题,可以通过删除其他比较函数(如 __lt__、__le__、__ne__、__gt__、__ge__)来启用 __cmp__ 函数。这样做可以确保列表的相等性判断符合预期。
需要注意的是,在 Python 3 中,即使没有基类,也似乎强制要求实现 __eq__ 函数,而仅仅返回 0 的 __cmp__ 函数并不能确保相等性。在 Python 3 中,完全不再使用 __cmp__ 函数。
根据需要实现列表包装器的要求,我们可以选择在 Python 2 中使用 __cmp__ 函数或在 Python 3 中使用 __eq__ 函数来实现相等性判断。