[python] 파이썬 사용자 정의 클래스를 정렬 가능하고 해시 가능하게 만들기

파이썬에서 사용자 정의 클래스를 정렬 가능 및 / 또는 해시 가능하게 만들 때 어떤 메서드를 재정의 / 구현해야합니까?

주의해야 할 점은 무엇입니까?

dir({})인터프리터에 입력 하여 내장 딕셔너리에 대한 메소드 목록을 얻습니다. 그중 일부를 구현해야한다고 가정합니다.

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

Python2와 달리 Python3에 대해 구현해야하는 메서드에 차이가 있습니까?



답변

나는 이것을 다른 답변에 대한 의견으로 거의 게시했지만 실제로는 그 자체로 답변입니다.

항목을 정렬 가능하게 만들려면 __lt__. 이것이 내장 정렬에서 사용되는 유일한 방법입니다.

다른 비교는 또는 functools.total_ordering클래스와 함께 비교 연산자를 실제로 사용하려는 경우에만 필요합니다.

항목을 해시 할 수 있도록하려면 __hash__다른 사람들이 언급 한대로 구현 합니다. 또한 __eq__호환 가능한 방식으로 구현 해야합니다. 동일한 항목은 동일하게 해시해야합니다.


답변

Python 2와 3에는 차이가 없습니다.

정렬 가능성 :

비교 방법을 정의해야합니다. 이렇게하면 항목을 정렬 할 수 있습니다. 일반적으로 __cmp__().

나는 보통 functools.total_ordering 데코레이터를 사용합니다.

functools.total_ordering (cls) 하나 이상의 풍부한 비교 순서 지정 방법을 정의하는 클래스가 주어지면이 클래스 데코레이터가 나머지를 제공합니다. 이렇게하면 가능한 모든 풍부한 비교 연산을 지정하는 데 드는 노력이 간소화됩니다.

클래스 중 하나 정의해야합니다 __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)

그리고 사용자 정의 __hash__함수 를 정의하려면 마지막을 정의해야합니다 . 문서를 참조하십시오 .


답변

구현 __lt__(self,other)방법은 클래스를 정렬 가능하게 만드는 대답입니다.
내장 메소드 sorted(iterable)뿐만 아니라 heapq모듈을 통한 우선 순위 큐에도 사용할 수 있습니다 .

게다가 저는 파이썬의 디자인이 마음에 들지 않아서 많은 '__ge__', '__gt__', '__le__', '__lt__', '__ne__'방법이 전혀 직관적이지 않습니다 !
대조적으로 Java Interface Comparable<T> ( java doc 참조 )는이 객체가 직접적이고 친숙한 지정된 객체보다 작거나 같거나 크므로 음의 정수, 0 또는 양의 정수를 반환합니다 !


답변