2010-03-28 10 views
25

세트로 바꾸고 싶은 오브젝트 목록이 있습니다. 내 개체에는 몇 가지 필드가 포함되어 있는데 그 중 일부는 o.ido.area입니다. 이 두 필드가 같으면 두 객체가 같아야합니다. 예 : o1==o2o1.area==o2.area and o1.id==o2.id 인 경우에만 해당됩니다.Python : 어떻게 세트가 작동합니까?

__eq____cmp__을 덮어 쓰려고했지만 오류가 발생했습니다 : TypeError: unhashable instance.

무엇을 덮어 써야합니까?

+3

http://docs.python.org/library/stdtypes.html#set-types-set-frozenset 및 http://docs.python.org/glossary.html#term-hashable –

답변

38

__hash__ 메서드를 정의하여 ID 및 영역 필드를 기반으로 의미있는 해시를 반환하십시오. 예 :

def __hash__(self): 
    return hash(self.id)^hash(self.area) 
+13

조금 있습니다. 그런 식의 비트 수학에 대한 경계심. 나는 = return hash ((self.id, self.area)) =와 같은 것을 사용할 것이다. –

+1

두 개의 유사한 구성 요소를 해시 할 때 문제가 될 수 있습니다. 예를 들어 해시 (x)^해시 (y)는 스왑 된 축과 좌표 쌍이 공통적 인 경우 오작동합니다. 이 경우 상관 된 해시를 사용하여 int 및 문자열을 생성 할 수 없기 때문에 문제가 발생할 가능성은 극히 적습니다. 그렇게 말하면서, 당신의 제안은 여전히 ​​좋은 생각인데, 나는 그것을 생각했다 .--). –

9

"TypeError : unhashable instance." 오류가 아마도 이전 스타일 클래스 정의 즉이다 : 대신

class A: 
    pass 

를 사용하여 새로운 스타일 :

class A(object): 
    pass 

당신이 __cmp__ 함수를 재정의하는 경우 해야 세트에서 객체를 사용 재정의 __hash__. 다른 경우 해시는 모든 객체 인스턴스를 같지 않은 것으로 간주하고 __cmp__ 함수가 호출되지 않습니다.

관련 문제