使python用户定义的类可排序,可清除

时间:2011-08-22 19:25:07

标签: python class sorting hash magic-methods

在python中对用户定义的类进行排序和/或哈希时,需要覆盖/实现哪些方法?

有什么值得注意的?

我在我的解释器中输入dir({})以获取内置dicts的方法列表。其中,我假设我需要实现一些

的子集
['__cmp__', '__eq__', '__ge__', '__gt__', '__hash__', '__le__', '__lt__', '__ne__']

与Python2相比,Python3必须实现哪些方法有区别?

4 个答案:

答案 0 :(得分:68)

我几乎将此作为对其他答案的评论发布,但它本身就是一个答案。

要使您的商品可排序,他们只需要实施__lt__。这是内置排序使用的唯一方法。

只有在您真正想要将比较运算符与您的班级一起使用时,才需要进行其他比较或functools.total_ordering

要使您的商品可以播放,请按照其他人的说明实施__hash__。您还应该以兼容的方式实现__eq__ - 相同的项应该使用相同的哈希值。

答案 1 :(得分:15)

Python 2和3之间没有任何区别。

可分类性:

您应该定义比较方法。这使您的商品可以排序。通常,您不应该更喜欢__cmp__()

我通常使用functools.total_ordering装饰器。

  

functools.total_ordering(cls)给定一个定义一个或多个rich的类   比较排序方法,这个类装饰器提供其余的。   这简化了指定所有可能的工作   丰富的比较操作:

     

该课程必须定义__lt__()__le__()__gt__()或其中一个   __ge__()。此外,该课程应提供__eq__()方法。

您应该注意比较方法是否有副作用。在进行比较时,您不希望更改班级。

用于散列:

您应该实施__hash__()方法。我认为最好的方法是返回hash(repr(self)),所以你的哈希值是唯一的。

答案 2 :(得分:2)

有几种方法可以将对象标记为可排序。第一个 - 丰富的比较,由一组函数定义:

object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)

也可以只定义一个函数:

object.__cmp__(self, other)

如果要定义自定义__hash__函数,则应定义最后一个。请参阅doc

答案 3 :(得分:-1)

实施__lt__(self,other)方法是让您的课程可排序的答案 它不仅可以用于内置方法sorted(iterable),还可以用于heapq模块的优先级队列。

另外,我不喜欢python的设计,因此很多'__ge__', '__gt__', '__le__', '__lt__', '__ne__'方法根本不直观
相比之下,Java的Interface Comparable<T>(请参阅java doc)返回负整数,零或正整数,因为此对象小于,等于或大于指定对象,即直接友好