파이썬에서 사용자 정의 클래스를 정렬 가능 및 / 또는 해시 가능하게 만들 때 어떤 메서드를 재정의 / 구현해야합니까?
주의해야 할 점은 무엇입니까?
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 또는 양의 정수를 반환합니다 !