Making a python user-defined class sortable, hashable

前端 未结 4 1094
执念已碎
执念已碎 2020-12-01 08:54

What methods need to be overridden/implemented when making user-defined classes sortable and/or hashable in python?

What are the gotchas to watch out for?

I

相关标签:
4条回答
  • 2020-12-01 09:12

    There isn't any difference between Python 2 and 3.

    For sortability:

    You should define comparision methods. This makes your items sortable. Generally, you shouldn't prefer __cmp__().

    I usually use functools.total_ordering decorator.

    functools.total_ordering(cls) Given a class defining one or more rich comparison ordering methods, this class decorator supplies the rest. This simplifies the effort involved in specifying all of the possible rich comparison operations:

    The class must define one of __lt__(), __le__(), __gt__(), or __ge__(). In addition, the class should supply an __eq__() method.

    You should be careful that your comparison methods do not have any side effects. (change any of the values of the object)

    For hashing:

    You should implement __hash__() method. I think the best way is returning hash(repr(self)), so your hash would be unique.

    0 讨论(0)
  • 2020-12-01 09:18

    Implement __lt__(self,other) method is the answer to make your class sortable.
    It can be used for not only the built-in method sorted(iterable), but also priority queue via heapq module.

    In addition, I don't like python's design, so many '__ge__', '__gt__', '__le__', '__lt__', '__ne__' methods are not intuitive at all !
    As a contrast, Java's Interface Comparable<T> (see java doc) returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object, which is direct and friendly!

    0 讨论(0)
  • 2020-12-01 09:33

    There are a few ways of marking your object sortable. First - rich comparison, defined by a set of functions:

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

    Also it is possible to define only one function:

    object.__cmp__(self, other)
    

    And the last should be defined if you want to define custom __hash__ function. See the doc.

    0 讨论(0)
  • 2020-12-01 09:36

    I almost posted this as a comment to the other answers but it's really an answer in and of itself.

    To make your items sortable, they only need to implement __lt__. That's the only method used by the built in sort.

    The other comparisons or functools.total_ordering are only needed if you actually want to use the comparison operators with your class.

    To make your items hashable, you implement __hash__ as others noted. You should also implement __eq__ in a compatible way -- items that are equivalent should hash the same.

    0 讨论(0)
提交回复
热议问题