`__eq__`를 정의하는 유형은 해시 할 수 없습니까?
내 프로그램의 Python 3.1 포크로 기능을 이식 할 때 이상한 버그가있었습니다. 나는 그것을 다음 가설로 좁혔다.
Python 2.x와 달리 Python 3.x에서는 객체에 __eq__
메서드가 있으면 자동으로 해시 할 수 없습니다.
이것이 사실입니까?
Python 3.1에서 일어나는 일은 다음과 같습니다.
>>> class O(object):
... def __eq__(self, other):
... return 'whatever'
...
>>> o = O()
>>> d = {o: 0}
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
d = {o: 0}
TypeError: unhashable type: 'O'
후속 질문은 개인 문제를 어떻게 해결합니까? 나는 과거의 특정 시점에 피클 덤프의 값을 각각 제공하는 여러 개체를 가리키는를 ChangeTracker
저장 하는 개체 가 있습니다 WeakKeyDictionary
. 기존 개체가 체크인 될 때마다 변경 추적기는 새 피클이 이전 피클과 동일한 지 여부를 알려주므로 그 동안 개체가 변경되었는지 여부를 알려줍니다. 문제는 이제 주어진 객체가 라이브러리에 있는지 확인할 수 없다는 것입니다. 객체가 해시 불가능하다는 예외를 발생시키기 때문입니다. (왜냐하면 __eq__
방법 이 있기 때문 입니다.)이 문제를 어떻게 해결할 수 있습니까?
예, 정의 __eq__
하면 기본값 __hash__
(즉, 메모리에서 객체의 주소를 해싱)이 사라집니다. 이것은 해싱이 동일성과 일치해야하기 때문에 중요합니다. 동일한 객체는 동일하게 해시해야합니다.
해결책은 간단합니다. 정의 __hash__
와 함께 정의하기 만하면 __eq__
됩니다.
http://docs.python.org/3.1/reference/datamodel.html#object 의이 단락 . 해시시
재정의하는 클래스가 부모 클래스
__eq__()
의 구현을 유지__hash__()
해야하는 경우 인터프리터는를 설정하여이를 명시 적으로 알려야합니다__hash__ = <ParentClass>.__hash__
. 그렇지 않으면 명시 적으로 None으로 설정 한__hash__()
것처럼 상속 이 차단됩니다__hash__
.
다음에서 Python 3 설명서를 확인하십시오 object.__hash__
.
클래스가
__eq__()
메서드를 정의하지 않으면__hash__()
작업도 정의해서는 안됩니다 . 정의__eq__()
하지만 그렇지 않은__hash__()
경우 해당 인스턴스는 해시 가능한 컬렉션의 항목으로 사용할 수 없습니다.
강조는 내 것입니다.
게으르고 싶다면 __hash__(self)
return을 정의 할 수 있습니다 id(self)
.
사용자 정의 클래스에는 기본적으로
__eq__()
및__hash__()
메서드가 있습니다. 그들과 함께, 모든 객체는 불평등을 비교하고 (자신을 제외하고)를x.__hash__()
반환합니다id(x)
.
저는 파이썬 전문가는 아니지만 eq-method를 정의 할 때 해시 방법도 정의해야한다는 것이 말이되지 않을 것입니다 (객체의 해시 값을 계산 함) 그렇지 않으면 해싱 메커니즘 동일한 객체에 도달했는지 또는 동일한 해시 값을 가진 다른 객체에 도달했는지 알 수 없습니다. 실제로는 그 반대입니다. 아마도 당신의 __eq__
방법에 의해 동일하다고 간주되는 객체에 대해 다른 해시 값을 계산하게 될 것 입니다.
나는 그 해시 함수가 무엇인지 __hash__
모르겠다. :)
참고 URL : https://stackoverflow.com/questions/1608842/types-that-define-eq-are-unhashable
'programing' 카테고리의 다른 글
이 방법으로 인해 무한 루프가 발생하는 이유는 무엇입니까? (0) | 2020.11.21 |
---|---|
구성 요소 당 하나의 파일 또는 구성 요소 당 여러 파일? (0) | 2020.11.21 |
"타이트 루프"란 무엇입니까? (0) | 2020.11.21 |
Google Suggest API에 대한 문서는 어디에 있습니까? (0) | 2020.11.21 |
Ubuntu를 시작할 때 스크립트를 실행하는 방법은 무엇입니까? (0) | 2020.11.21 |