`__eq__`를 정의하는 유형은 무시할 수 없습니까?
-
05-07-2019 - |
문제
내 프로그램의 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
저장 a WeakKeyDictionary
이는 여러 개체를 가리키며 과거의 특정 시점에서 피클 덤프의 값을 각각마다 제공합니다. 기존 객체를 체크인 할 때마다 변경 추적기는 새 피클이 이전 객체와 동일했는지 여부를 말하면 그 동안 객체가 바뀌 었는지 여부를 말합니다. 문제는 이제 주어진 객체가 라이브러리에 있는지 확인할 수 없다는 것입니다. 왜냐하면 그것은 객체가 무시할 수없는 것에 대한 예외를 제기하기 때문입니다. (a __eq__
방법.)이 문제를 어떻게 해결할 수 있습니까?
해결책
예, 정의하면 __eq__
, 기본값 __hash__
(즉, 메모리에서 객체의 주소를 해싱) 사라집니다. 해싱은 평등과 일치해야하기 때문에 중요합니다. 동등한 물체는 동일하게 해시해야합니다.
솔루션은 간단합니다. 정의하십시오 __hash__
정의와 함께 __eq__
.
다른 팁
이 단락에서 http://docs.python.org/3.1/reference/datamodel.html#object해시시
무시하는 클래스 인 경우
__eq__()
구현을 유지해야합니다__hash__()
부모 수업에서 통역사는 설정하여 명시 적으로 말해야합니다.__hash__ = <ParentClass>.__hash__
. 그렇지 않으면 상속__hash__()
마치 마치 마치 차단됩니다__hash__
명시 적으로 아무도 설정되지 않았습니다.
Python 3 매뉴얼을 확인하십시오 object.__hash__
:
클래스가 정의하지 않는 경우
__eq__()
메소드 a를 정의해서는 안됩니다__hash__()
작업 중 하나; 그것이 정의된다면__eq__()
하지만__hash__()
, 해시블 컬렉션의 항목으로 인스턴스는 사용할 수 없습니다.
강조는 내 것입니다.
게으르고 싶다면 단지 정의 할 수있는 것 같습니다. __hash__(self)
돌려 주다 id(self)
:
사용자 정의 클래스가 있습니다
__eq__()
그리고__hash__()
기본적으로 방법; 그들과 함께 모든 물체는 불평등 한 (자신과 함께) 비교하고x.__hash__()
보고id(x)
.
나는 Python Expert가 아니지만 EQ- 방법을 정의 할 때 해시 메드 (객체의 해시 값을 계산하는 것)도 해싱 메커니즘을 정의해야한다는 것은 의미가 없을 것입니다. 동일한 객체에 부딪 치거나 같은 해시 가치가있는 다른 물체에 닿는 지 알 수 없습니다. 실제로, 그것은 다른 방법입니다. 아마도 당신의 동등한 것으로 간주되는 객체에 대해 다른 해시 값을 계산하게 될 것입니다. __eq__
방법.
해시 기능이 무엇인지 모르겠습니다. __hash__
아마도? :)