Создание пользовательского класса python сортируемый, хешируемый


какие методы должны быть переопределены / реализованы при создании пользовательских классов сортируемых и / или хэшируемых в python?

каких подводных камней следует остерегаться?

я типа dir({}) на мой переводчик, чтобы получить список методов, на встроенный словарь. Из них я предполагаю, что мне нужно реализовать некоторое подмножество

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

есть ли разница в том, какие методы должны быть реализованы для Python3 в отличие от Python2?

4 53

4 ответа:

я почти разместил это как комментарий к другим ответам, но это действительно ответ сам по себе.

чтобы сделать ваши предметы сортируемыми, их нужно только реализовать __lt__. Это единственный метод, используемый встроенной сортировкой.

другие сравнения или functools.total_ordering необходимы только в том случае, если вы действительно хотите использовать операторы сравнения с вашим классом.

сделать ваши вещи hashable, вы реализуете __hash__ Как отмечали другие. Вы также должны реализовать __eq__ совместимым образом -- эквивалентные элементы должны иметь одинаковый хэш.

нет никакой разницы между Python 2 и 3.

для возможности сортировки:

вы должны определить методы сравнения. Это делает ваши предметы сортируемыми. Как правило, вы не должны предпочитать __cmp__().

Я обычно использую functools.total_ordering декоратор.

functools.total_ordering(КНК) с учетом класса, определяющего один или более богатый сравнение методов заказа, этот класс декоратор поставляет остальное. Это упрощает усилия, связанные с указанием всех возможных богатые операции сравнения:

класс должен определить один из __lt__(),__le__(),__gt__(), или __ge__(). Кроме того, класс должен предоставить __eq__() метод.

вы должны быть осторожны для ваших методов сравнения для иметь побочный эффект. Вы не хотите, чтобы ваш класс изменился при выполнении сравнений.

для хэширования:

вы должны реализовать __hash__() метод. Я думаю, что лучший способ-это возвращение hash(repr(self)), так что ваш хэш-код будет уникальным.

есть несколько способов маркировки объекта сортировки. Первое-богатое сравнение, определяемое набором функций:

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)

и последнее должно быть определено, если вы хотите определить пользовательские

реализовать __lt__(self,other) метод-это ответ, чтобы сделать ваш класс сортируемым.
Его можно использовать не только для встроенного метода sorted(iterable), но также приоритет очереди через heapq модуль.

кроме того, мне не нравится дизайн python, так много '__ge__', '__gt__', '__le__', '__lt__', '__ne__' методы совсем не интуитивный !
В отличие от этого, Java Interface Comparable<T> (см. документации) возвращает отрицательное целое число, ноль или положительное целое число, поскольку этот объект меньше, равен или больше чем указанный объект, который является прямой и дружественный!