Как тестирование членства отличается для списка и набора?
мне трудно понять, почему первое из этих утверждений в порядке, а второе вызывает ошибку.
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)
здесь ошибка:
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
, и в другом UnitTest я проверяю, что Subject("A") == Subject("A")
. Я действительно не могу понять, почему тему в списке, а не в наборе. В идеале я хотел бы, чтобы тема была в обоих.
4 ответов
выражение
Subject("A") in subject_list
сравнить Subject("A")
к каждой записи в subject_list
С помощью Subject.__eq__()
метод. Если этот метод не перезаписан, по умолчанию он всегда возвращает False
если только два операнда не являются тот же объект. Вышеприведенное выражение всегда будет возвращать False
если Subject
не хватает __eq__()
метод, так как Subject("A")
- это новый экземпляр, который уже не может быть в списке.
выражение
Subject("A") in subject_set
на наоборот будет использовать Subject.__hash__()
сначала найдите нужное ведро и используйте Subject.__eq__()
только после этого. Если вы не определили Subject.__hash__()
в соответствии с Subject.__eq__()
, это не удастся.
членство в наборе также зависит от хэша объекта, и поэтому вы должны реализовать __hash__()
метод в классе соответствующим образом.
либо у вас нет __hash__()
метод Subject
класс, или это хитроумный. Попробуйте это:
def __hash__(self):
return hash(self.name)
документы здесь.
чтобы использовать их в наборе, вы должны убедиться Subject
правильно hashable. Если вы не определяете __hash__
себя, он просто возьмет id
, и это отличается для разных экземпляров. __hash__
должно быть определено таким, что равные объекты имеют одинаковый хэш.