¿Qué métodos deben anularse / implementarse al hacer que las clases definidas por el usuario se puedan ordenar y / o tener hash en Python?
¿Cuáles son las trampas a tener en cuenta?
Tipo I dir({})
en mi intérprete para obtener una lista de métodos de dicts incorporado. De ellos, supongo que necesito implementar algún subconjunto de
['__cmp__', '__eq__', '__ge__', '__gt__', '__hash__', '__le__', '__lt__', '__ne__']
¿Hay alguna diferencia en qué métodos deben implementarse para Python3 en comparación con Python2?
__cmp__
se eliminó.Respuestas:
Casi publico esto como un comentario a las otras respuestas, pero en realidad es una respuesta en sí misma.
Para que sus elementos se puedan ordenar, solo necesitan implementarlos
__lt__
. Ese es el único método utilizado por la ordenación integrada.Las otras comparaciones o
functools.total_ordering
solo son necesarias si realmente desea utilizar los operadores de comparación con su clase.Para hacer que sus artículos sean hash, implemente
__hash__
como otros señalaron. También debe implementar__eq__
de una manera compatible: los elementos que son equivalentes deben usar el mismo hash.fuente
__lt__
Python podría hacer que se clasifique de manera impredecible? (por ejemplo, si x .__ lt __ (y) y y .__ lt __ (x))__key__
función que convierta la instancia en una tupla, luego haga que tanto__lt__
(self.__key__() < other.__key__()
) como__hash__
(hash(self.__key__())
) la usen.No hay ninguna diferencia entre Python 2 y 3.
Para ordenar:
Debe definir métodos de comparación. Esto hace que sus artículos se puedan ordenar. Generalmente, no debería preferir
__cmp__()
.Yo suelo usar el decorador functools.total_ordering.
Debe tener cuidado de que sus métodos de comparación no tengan efectos secundarios. (cambiar cualquiera de los valores del objeto)
Para hash:
Debes implementar el
__hash__()
método. Creo que la mejor forma es regresarhash(repr(self))
, para que tu hash sea único.fuente
functools.total_ordering
la documentación, consulte aquí .Hay algunas formas de marcar su objeto de forma ordenable. Primero: comparación rica, definida por un conjunto de funciones:
También es posible definir solo una función:
Y el último debe definirse si desea definir una
__hash__
función personalizada . Ver el doc .fuente
__cmp__()
método especial ya no es compatible", consulte la sección correspondiente aquí .El
__lt__(self,other)
método de implementación es la respuesta para hacer que su clase se pueda ordenar.Se puede utilizar no solo para el método integrado
sorted(iterable)
, sino también para la cola de prioridad a través delheapq
módulo.Además, no me gusta el diseño de Python, ¡muchos
'__ge__', '__gt__', '__le__', '__lt__', '__ne__'
métodos no son intuitivos en absoluto !Como contraste, Java
Interface Comparable<T>
(ver java doc ) devuelve un entero negativo, cero o un entero positivo ya que este objeto es menor, igual o mayor que el objeto especificado, ¡que es directo y amigable !fuente