Сравнение объектов по атрибутам в Python — простой пример
В этом уроке вы узнаете, как использовать метод __eq__ в Python для сравнения двух объектов по их атрибутам.
Пример использования метода __eq__ в Python
Предположим, что у вас есть следующий класс Person с тремя атрибутами экземпляра: first_name, Last_name и age:
class Person: def __init__(self, first_name, last_name, age): self.first_name = first_name self.last_name = last_name self.age = age
И вы создаете два экземпляра класса Person:
john = Person('John', 'Doe', 25) jane = Person('Jane', 'Doe', 25)
В этом примере объекты «John» и «Jane» не являются одним и тем же объектом. И вы можете проверить это с помощью оператора is:
print(john is jane) # False
Кроме того, когда вы сравниваете John и Jane, используя оператор равенства(==), вы получите результат False:
print(john == jane) # False
Поскольку John и Jane одного возраста, вы хотите, чтобы они были равны. Другими словами, вы хотите, чтобы следующее выражение возвращало значение True:
john == jane
Для этого вы можете реализовать метод __eq__ dunder в классе Person.
Python автоматически вызывает метод __eq__, когда вы используете оператор == для сравнения экземпляров класса. По умолчанию Python использует оператор is, если вы не предоставляете конкретную реализацию метода __eq__.
Ниже показано, как реализовать метод __eq__ в классе Person, который возвращает True, если два объекта person имеют одинаковый возраст:
class Person: def __init__(self, first_name, last_name, age): self.first_name = first_name self.last_name = last_name self.age = age def __eq__(self, other): return self.age == other.age
Теперь, если вы сравните два экземпляра класса Person одного возраста, он вернет True:
john = Person('John', 'Doe', 25) jane = Person('Jane', 'Doe', 25) print(john == jane) # True
А если два экземпляра класса Person имеют разный возраст, оператор == возвращает False:
john = Person('John', 'Doe', 25) mary = Person('Mary', 'Doe', 27) print(john == mary) # False
Здесь сравнивается объект Person с целым числом:
john = Person('John', 'Doe', 25) print(john == 20)
Возвращает ошибку:
AttributeError: 'int' object has no attribute 'age'
Чтобы исправить это, вы можете изменить метод __eq__, чтобы перед доступом к атрибуту age проверять, является ли объект экземпляром класса Person.
Если другой объект не является экземпляром класса Person, метод __eq__ возвращает False, например:
class Person: def __init__(self, first_name, last_name, age): self.first_name = first_name self.last_name = last_name self.age = age def __eq__(self, other): if isinstance(other, Person): return self.age == other.age return False
И теперь вы можете сравнить экземпляр класса Person с целым числом или любым объектом другого типа:
john = Person('John', 'Doe', 25) print(john == 20) # False
Собираем все вместе.
class Person: def __init__(self, first_name, last_name, age): self.first_name = first_name self.last_name = last_name self.age = age def __eq__(self, other): if isinstance(other, Person): return self.age == other.age return False john = Person('John', 'Doe', 25) jane = Person('Jane', 'Doe', 25) mary = Person('Mary', 'Doe', 27) print(john == jane) # True print(john == mary) # False john = Person('John', 'Doe', 25) print(john == 20) # False