Jakie metody należy przesłonić / zaimplementować podczas tworzenia klas zdefiniowanych przez użytkownika, które można sortować i / lub haszować w Pythonie?
Na co trzeba uważać?
Wpisuję dir({})
do mojego interpretera, aby uzyskać listę metod wbudowanych w dykty. Spośród nich zakładam, że muszę zaimplementować jakiś podzbiór plików
['__cmp__', '__eq__', '__ge__', '__gt__', '__hash__', '__le__', '__lt__', '__ne__']
Czy istnieje różnica w tym, które metody muszą zostać zaimplementowane w Pythonie3, a nie w Pythonie2?
__cmp__
został usunięty.Odpowiedzi:
Prawie opublikowałem to jako komentarz do innych odpowiedzi, ale tak naprawdę jest to odpowiedź sama w sobie.
Aby Twoje przedmioty można było sortować, wystarczy je zaimplementować
__lt__
. To jedyna metoda używana przez sortowanie wbudowane.Inne porównania lub
functools.total_ordering
są potrzebne tylko wtedy, gdy faktycznie chcesz użyć operatorów porównania w swojej klasie.Aby umożliwić haszowanie elementów, implementujesz je
__hash__
tak, jak zauważyli inni. Powinieneś także implementować__eq__
w sposób zgodny - elementy, które są równoważne, powinny haszować to samo.źródło
__lt__
może spowodować nieprzewidywalne sortowanie Pythona? (na przykład, jeśli x .__ lt __ (y) i y .__ lt __ (x))__key__
funkcję, która zamienia instancję w krotkę, a następnie po prostu użyj obu__lt__
(self.__key__() < other.__key__()
) i__hash__
(hash(self.__key__())
).Nie ma żadnej różnicy między Pythonem 2 i 3.
Do sortowania:
Należy zdefiniować metody porównawcze. Dzięki temu Twoje przedmioty można sortować. Generalnie nie powinieneś preferować
__cmp__()
.Zwykle używam dekoratora functools.total_ordering.
Należy uważać, aby metody porównawcze nie miały żadnych skutków ubocznych. (zmień dowolną wartość obiektu)
Do haszowania:
Powinieneś zaimplementować
__hash__()
metodę. Myślę, że najlepszym sposobem jest powróthash(repr(self))
, więc Twój haszysz byłby wyjątkowy.źródło
functools.total_ordering
zapoznać się z przykładem z dokumentacji, zobacz tutaj .Istnieje kilka sposobów oznaczenia obiektu jako możliwego do sortowania. Po pierwsze - bogate porównanie, zdefiniowane przez zestaw funkcji:
object.__lt__(self, other) object.__le__(self, other) object.__eq__(self, other) object.__ne__(self, other) object.__gt__(self, other) object.__ge__(self, other)
Możliwe jest również zdefiniowanie tylko jednej funkcji:
object.__cmp__(self, other)
A ostatnia powinna zostać zdefiniowana, jeśli chcesz zdefiniować
__hash__
funkcję niestandardową . Zobacz doc .źródło
__cmp__()
metoda specjalna nie jest już obsługiwana”, zobacz odpowiednią sekcję tutaj .__lt__(self,other)
Metoda implementacji jest odpowiedzią, która umożliwia sortowanie klasy.Może być używany nie tylko do metody wbudowanej
sorted(iterable)
, ale także do kolejkowania priorytetów przezheapq
moduł.Ponadto nie podoba mi się projekt Pythona, więc wiele
'__ge__', '__gt__', '__le__', '__lt__', '__ne__'
metod nie jest w ogóle intuicyjnych !Dla kontrastu, Java
Interface Comparable<T>
(patrz dokumentacja java ) zwraca ujemną liczbę całkowitą, zero lub dodatnią liczbę całkowitą, ponieważ ten obiekt jest mniejszy, równy lub większy niż określony obiekt, co jest bezpośrednie i przyjazne !źródło