2010-12-11 3 views

답변

18

__hash__ 메서드가있는 모든 객체는 사전 키가 될 수 있습니다. 당신이 쓰는 클래스의 경우, 값을 반환하려면이 메서드는 기본적으로 ID (자기)를 기반으로, 평등은 해당 클래스에 대한 정체성에 의해 결정되어 있지 않은 경우, 당신은 키로를 사용하여 놀랄 수

>>> class A(object): 
... def __eq__(self, other): 
...  return True 
... 
>>> one, two = A(), A() 
>>> d = {one: "one"} 
>>> one == two 
True 
>>> d[one] 
'one' 
>>> d[two] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyError: <__main__.A object at 0xb718836c> 

>>> hash(set()) # sets cannot be dict keys 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'set' 

버전 2.6에서 변경되었습니다 : __hash__을 None으로 설정하여 클래스 인스턴스를 해쉬 할 수없는 것으로 명시 적으로 표시 할 수 있습니다. [__hash__]

class Unhashable(object): 
    __hash__ = None 
6

요건은 객체의 해시가 시간에 따라 변화하지 않는 것으로하고, 그 원래의 값과 동일 (==) 비교 유지있다. 클래스 A는이 두 요구 사항을 모두 충족하므로 유효한 사전 키를 만듭니다. x 속성은 키잉에서 전혀 고려되지 않고, 객체 ID 만이 고려됩니다.

6

개체가 hashable 인 경우 사전의 키가 될 수 있습니다. 여기

는 문서로부터 해쉬의 정의이다

그것의 수명 동안 변경되지 않을 해시 값을 가지면 목적은 해쉬이다는 (그것이 __hash__() 방법이 필요), 및 다른 비교 될 수있다 개체 (__eq__() 또는 __cmp__() 메서드 필요). equal을 비교하는 해시 가능 객체는 동일한 해시 값을 가져야합니다.

해시 가능성 (Hashability)은 해시 값을 내부적으로 사용하기 때문에 해시 성은 개체를 사전 키 및 집합 멤버로 사용할 수있게합니다.

변경 가능한 모든 컨테이너 (예 : 목록 또는 사전)는 존재하지 않지만 모든 Python의 변경 불가능한 내장 객체는 해시 가능합니다. 사용자 정의 클래스의 인스턴스 인 객체는 기본적으로 해시 가능합니다. 그들은 모두 같지 않은 것을 비교하고 해시 값은 id()입니다. object 이후

이이 명시 적으로 해쉬 수 없습니다 정의하지 않는 한 object에서 파생 아무것도 해쉬 것을 의미 __hash__, __eq____cmp__의 기본 구현을 제공합니다. 해시 가능 인 변경 가능 유형을 작성하는 것이 허용되지 않지만 원하는대로 작동하지 않을 수 있습니다. 프레드 - nurk의 예 @

1

위 다행히 때문에 더 이상 this change의 파이썬 3에서 작동하지 않습니다 :

__eq__()을 무시하고 __hash__() 암시 None로 설정해야합니다 __hash__()를 정의하지 않는 클래스입니다. 클래스의 __hash__() 방법은 None 경우 프로그램이 자신의 해시 값을 검색하려고 할 때, 클래스의 인스턴스는

그 하나님 께 감사를드립니다 ... 적절한 TypeError을 올릴 것이다.그러나 직접 __hash__()을 정의하면 여전히 악의적 인 일을 할 수 있습니다.

class BadHasher: 
    def __init__(self): 
     self.first = True 

    # Implement __hash__ in an evil way. The first time an instance is hashed, 
    # return 1. Every time after that, return 0. 
    def __hash__(self): 
     if self.first: 
      self.first = False 
      return 1 
     return 0 

myobject = BadHasher() 
# We can put this object in a set... 
myset = {myobject} 
# ...but as soon as we look for it, it's gone! 
if myobject not in myset: 
    print("what the hell we JUST put it in there") 
관련 문제