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

Mat*_*ick 70 python sorting hash class magic-methods

在python中使用户定义的类可排序和/或可清除时,需要覆盖/实现哪些方法?

有什么值得注意的?

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

['__cmp__', '__eq__', '__ge__', '__gt__', '__hash__', '__le__', '__lt__', '__ne__']
Run Code Online (Sandbox Code Playgroud)

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

agf*_*agf 78

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

要使您的项目可排序,他们只需要实现__lt__.这是内置排序使用的唯一方法.

其他比较或functools.total_ordering仅在您真正想要将比较运算符与您的类一起使用时才需要.

为了使您的物品可以清洗,您可以__hash__像其他人那样实施.您还应该__eq__以兼容的方式实现 - 等效的项应该散列相同.

  • 我不知道"不可预测",如果输入完全相同的输入,它将是一致的,但是不同的输入顺序可能导致不同的项目处于不同的顺序.是的,如果你不正确地实现用于排序的比较,Python将不正确地排序.我建议使用`__key__`函数将实例转换为元组,然后只需要`__lt__`(`self .__ key __()<other .__ key __()`)和`__hash__`(`hash(self .__ key__) ())`)使用它. (3认同)

utd*_*mir 18

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

可分类性:

您应该定义比较方法.这使您的商品可以排序.一般来说,你不应该喜欢__cmp__().

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

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

这个类必须定义之一__lt__(),__le__(),__gt__(),或 __ge__().此外,该课程应该提供一种__eq__()方法.

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

对于散列:

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

  • 有关文档中“functools.total_ordering”的示例,请参阅[此处](https://docs.python.org/2/library/functools.html#functools.total_ordering)。 (2认同)

Rom*_*huk 7

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

object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)
Run Code Online (Sandbox Code Playgroud)

也可以只定义一个函数:

object.__cmp__(self, other)
Run Code Online (Sandbox Code Playgroud)

__hash__如果您想定义自定义函数,则应定义最后一个。请参阅文档

  • 在 Python 3 中,“[...]不再支持 `__cmp__()` 特殊方法,”请参阅[此处的相关部分](https://docs.python.org/release/3.0.1/whatsnew/ 3.0.html#ordering-comparisons)。 (9认同)