Как тестирование членства отличается для списка и набора?
мне трудно понять, почему первое из этих утверждений в порядке, а второе вызывает ошибку.
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__ должно быть определено таким, что равные объекты имеют одинаковый хэш.