2011-03-08 2 views
8

나는 왜이 단언의 첫번째 것이 OK이고 두번째 단 하나는 과실을 제기하는지 파악에 말썽이있다.목록과 집합에 대한 회원 테스트의 차이점은 무엇입니까?

Traceback (most recent call last): 
    File "C:\Users\...\testSubject.py", line 34, in testIn 
    self.assertIn(Subject("A"), subject_set) 
AssertionError: <Subject: A> not found in set([<Subject: B>, <Subject: C>, <Subject: A>]) 

제목 클래스의 평등에 대한 시험은 단순히 self.name == other.name이며, 다른 유닛 테스트에서 내가 그 Subject("A") == Subject("A")을 확인 : 여기

subject_list = [Subject("A"), Subject("B"), Subject("C")] 
subject_set = set() 
subject_set.add(Subject("A")) 
subject_set.add(Subject("B")) 
subject_set.add(Subject("C")) 

self.assertIn(Subject("A"), subject_list) 
self.assertIn(Subject("A"), subject_set) 

는 오류입니다. 주제가 목록에있는 이유는 무엇인지 알 수 없습니다. 이상적으로 나는 그 주제가 둘 다에 있기를 바란다.

답변

11

Subject.__eq__()subject_list 방법을 이용하여 각 항목에 Subject("A") 비교한다

Subject("A") in subject_list 

표현. 이 메서드를 덮어 쓰지 않으면 두 피연산자가 같은 개체이 아닌 한 항상 False을 반환합니다. 에 __eq__() 메서드가없는 경우 위의 식은 항상 False을 반환합니다. Subject("A")은 이미 목록에없는 새 인스턴스이므로이 메서드는 항상 False을 반환합니다.

에만이 오른쪽 버킷을 찾아 Subject.__eq__()를 사용하는 Subject.__hash__() 처음 사용할 반대로 표현

Subject("A") in subject_set 

. 과 호환되는 방식으로 Subject.__hash__()을 정의하지 않은 경우이 작업은 실패합니다.

+0

고마워요! Subject 클래스에서 __hash __() 함수를 구현하면이 문제가 해결됩니다. – rtclay

2

집합에서 이들을 사용하려면 Subject이 적절하게 해시 가능해야합니다. __hash__을 직접 정의하지 않으면 id이 걸리고 다른 인스턴스에 따라 다릅니다. __hash__은 동일한 객체가 동일한 해시를 갖도록 정의되어야합니다.

3

Subject 클래스에 __hash__() 메서드가 없거나 dodgy입니다. 사용해보기 :

def __hash__(self): 
    return hash(self.name) 

문서는 here입니다.

4

집합의 구성원도 개체의 해시에 따라 다르므로 클래스에 __hash__() 메서드를 적절히 구현해야합니다.

관련 문제