如何对列表和集合进行成员资格测试?

rtc*_*lay 8 python list set member

我无法弄清楚为什么第一个断言是正常的,第二个引发错误.

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)
Run Code Online (Sandbox Code Playgroud)

这是错误:

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>])
Run Code Online (Sandbox Code Playgroud)

Subject类中的相等性测试很简单self.name == other.name,在另一个UnitTest中我验证了Subject("A") == Subject("A").我真的无法弄清楚为什么主题在列表中而不在集合中.理想情况下,我希望这两个主题都存在.

Sve*_*ach 12

表达方式

Subject("A") in subject_list
Run Code Online (Sandbox Code Playgroud)

将与使用该方法的Subject("A")每个条目进行比较.如果不覆盖此方法,则默认始终返回,除非两个操作数是同一个对象.如果缺少方法,则上述表达式将始终返回,因为它是一个新的实例,它不能已经在列表中.subject_listSubject.__eq__()FalseFalseSubject__eq__()Subject("A")

表达方式

Subject("A") in subject_set
Run Code Online (Sandbox Code Playgroud)

相反将Subject.__hash__()首先使用找到合适的桶,并Subject.__eq__()在此之后使用.如果您没有Subject.__hash__()以兼容的方式定义Subject.__eq__(),则会失败.