2009-08-26 2 views
5

, 나는 이렇게 생각 : 클래스 ID 번호로 해시지고 같은 것을 바탕으로파이썬 클래스를 해시하는 것이 좋은 생각입니까? 예를 들어

>>> class foo(object): 
...  pass 
... 
>>> class bar(foo): 
...  pass 
... 
>>> some_dict = { foo : 'foo', 
... bar : 'bar'} 
>>> 
>>> some_dict[bar] 
'bar' 
>>> some_dict[foo] 
'foo' 
>>> hash(bar) 
165007700 
>>> id(bar) 
165007700 

, 그것은 보인다. 따라서 bar 해시를 foo 또는 bar으로 해시하거나 클래스를 변경하면 해시 값이 변경 될 염려는 없습니다.

이 동작을 신뢰할 수 있습니까? 아니면 여기에 문제가 있습니까?

답변

8

예, 해시 할 때 __hash__() 함수를 구현하지 않는 객체는 ID를 반환합니다. Python Language Reference: Data Model - Basic Customization에서 :

사용자 정의 클래스는 기본적으로 __cmp__()__hash__() 방법이있다; 그들과 함께, 모든 객체는 (자신을 제외하고) 불평등을 비교하며 x.__hash__()id(x)을 반환합니다.

그러나 고유 한 식별자가 필요하다면 id을 사용하여 의도를 분명히하십시오. 객체의 해시는 해당 구성 요소의 해시 조합이어야합니다. 자세한 내용은 위의 링크를 참조하십시오.

+2

* metaclass *에 __hash __() 함수가없는 클래스. –

+0

이것이 "파이썬 2.6의 새로운 기능"페이지에 있지만,이 동작은 파이썬 2.4에서 작동하는 것처럼 보입니다. –

+1

@ Jason 일반 문서에 대한 참조가 변경되었습니다. –

6

클래스는 각각 id()을 사용하여 해시 값을 계산하는 __eq____hash__의 기본 구현을 갖습니다. 즉, 그들은 신분으로 비교합니다. __hash__ 메서드를 구현하는 기본 규칙은 두 개체가 서로 동일하게 비교되는 경우에도 동일한 해시 값을 가져야합니다. 해시 값은 dicts와 sets에 의해 사용되는 최적화로 볼 수 있습니다. 결과적으로 __eq__을 변경하여 다른 종류의 평등 테스트를 수행하는 경우 __hash__ 구현을 해당 선택에 동의하도록 변경해야합니다.

비교를 위해 ID를 사용하는 클래스는 ID가 변경되지 않기 때문에 자유롭게 변형하여 사용할 수 있습니다. __eq__을 구현하여 값으로 비교하고 해당 값의 변경을 허용하는 클래스는 해시 모음에서 사용할 수 없습니다.