example - Haciendo una clase definida por el usuario python ordenable, hashable
python hash function (4)
Casi escribí esto como un comentario para las otras respuestas, pero en realidad es una respuesta en sí misma.
Para que sus artículos puedan __lt__
, solo necesitan implementar __lt__
. Ese es el único método utilizado por el tipo integrado.
Las otras comparaciones o functools.total_ordering
solo son necesarios si realmente desea utilizar los operadores de comparación con su clase.
Para que sus elementos sean lavables, implemente __hash__
como lo anotaron otros. También debe implementar __eq__
de una manera compatible: los elementos que son equivalentes deberían tener el hash igual.
¿Qué métodos deben ser reemplazados / implementados al hacer las clases definidas por el usuario ordenables y / o hashables en python?
¿Cuáles son los problemas que hay que tener en cuenta?
Escribo dir({})
en mi intérprete para obtener una lista de métodos en dicts integrados. De ellos, supongo que necesito implementar algún subconjunto de
[''__cmp__'', ''__eq__'', ''__ge__'', ''__gt__'', ''__hash__'', ''__le__'', ''__lt__'', ''__ne__'']
¿Hay alguna diferencia en cuanto a qué métodos se deben implementar para Python3 en comparación con Python2?
Hay algunas maneras de marcar su objeto ordenable. Primera comparación rica, definida por un conjunto de funciones:
object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)
También es posible definir solo una función:
object.__cmp__(self, other)
Y el último se debe definir si desea definir la función personalizada __hash__
. Ver el doc .
Implementar el __lt__(self,other)
es la respuesta para hacer que tu clase sea ordenable.
Se puede utilizar no solo para el método integrado sorted(iterable)
, sino también para la cola de prioridad a través del módulo heapq
.
Además, no me gusta el diseño de Python, ¡muchos ''__ge__'', ''__gt__'', ''__le__'', ''__lt__'', ''__ne__''
no son para nada intuitivos !
Como contraste, la Interface Comparable<T>
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 !
No hay ninguna diferencia entre Python 2 y 3.
Para la capacidad de adaptación:
Debe definir métodos de comparación. Esto hace que tus artículos puedan ordenarse. Generalmente, no deberías preferir __cmp__()
.
Usualmente uso functools.total_ordering decorator.
functools.total_ordering (cls) Dada una clase que define uno o más métodos de ordenamiento de comparación, este decorador de clase suministra el resto. Esto simplifica el esfuerzo involucrado en la especificación de todas las posibles operaciones de comparación enriquecidas:
La clase debe definir uno de
__lt__()
,__le__()
,__gt__()
o__ge__()
. Además, la clase debe proporcionar un__eq__()
.
Debe tener cuidado con sus métodos de comparación para tener efectos secundarios. No quieres que tu clase cambie cuando haces comparaciones.
Para hash:
Debe implementar el __hash__()
. Creo que la mejor manera es devolver hash(repr(self))
, por lo que su hash sería único.