123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- '''
- Операции сравнения и hash - функция
- __eq__ - == (противоположный __ne__)
- __ne__ - != (противоположный __eq__)
- __lt__ - < (противоположный __gt__)
- __le__ - <= (противоположный __ge__)
- __gt__ - > (противоположный __lt__)
- __ge__ - >= (противоположный __le__)
- Для сокращения кода можно спользовать @total_ordering
- hash() - можно взять только от неизменяемых объектов
- Хешируемые объекты могут быть ключами в словарях и элементов множества.
- '''
- from functools import total_ordering
- class OldRectangle:
- def __init__(self, a, b):
- self.a = a
- self.b = b
- @property
- def area(self):
- return self.a * self.b
- '''self - левая сторона, other - правая сторона'''
- ''' Если делать проверку на !=, то питон вызовет противоположный метод'''
- def __eq__(self, other):
- print('__eq__ call')
- if isinstance(other, OldRectangle):
- return self.a == other.b and self.b == other.b
-
- '''метод меньше'''
- def __lt__(self, other):
- print('__lt__ call')
- if isinstance(other, OldRectangle):
- return self.area < other.area
- if isinstance(other, (int, float)):
- return self.area < other
-
- '''Вызовет методы __eq__ и __lt__'''
- def __le__(self, other):
- return self==other or self<other
-
- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- class ChessPlayer:
- def __init__(self, name, surname, rating):
- self.name = name
- self.surname = surname
- self.rating = rating
- def __eq__(self, other):
- if isinstance(other, ChessPlayer):
- return self.rating == other.rating
- elif isinstance(other, int):
- return self.rating == other
- else:
- return 'Невозможно выполнить сравнение'
-
- def __gt__(self, other):
- if isinstance(other, ChessPlayer):
- return self.rating > other.rating
- elif isinstance(other, int):
- return self.rating > other
- else:
- return 'Невозможно выполнить сравнение'
-
- def __lt__(self, other):
- if isinstance(other, ChessPlayer):
- return self.rating < other.rating
- elif isinstance(other, int):
- return self.rating < other
- else:
- return 'Невозможно выполнить сравнение'
-
- def test_1():
- magnus = ChessPlayer('Carlsen', 'Magnus', 2847)
- assert magnus.name == 'Carlsen'
- assert magnus.surname == 'Magnus'
- assert magnus.rating == 2847
- ian = ChessPlayer('Ian', 'Nepomniachtchi', 2789)
- assert not magnus == 4000
- assert ian == 2789
- assert not magnus == ian
- assert magnus > ian
- assert not magnus < ian
- assert (magnus < [1, 2]) == 'Невозможно выполнить сравнение'
- v1 = ChessPlayer('Гарри ', 'Каспаров', 10)
- v2 = ChessPlayer('Бобби', 'Фишер', 20)
- v3 = ChessPlayer('Bot', 'Bot', 20)
- assert isinstance(v1, ChessPlayer)
- assert isinstance(v2, ChessPlayer)
- assert v2.__dict__ == {'name': 'Бобби', 'surname': 'Фишер', 'rating': 20}
- assert v1.__dict__ == {'name': 'Гарри ', 'surname': 'Каспаров', 'rating': 10}
- assert v1 > 5
- assert not v1 > 10
- assert not v1 > 11
- assert not v1 < 5
- assert not v1 < 10
- assert v1 < 11
- assert not v1 == 5
- assert v1 == 10
- assert not v1 == 11
- assert not v1 > v2
- assert not v1 == v2
- assert v3 == v2
- assert not v3 != v2
- assert v1 < v2
- assert (v1 > 'fdsfd') == 'Невозможно выполнить сравнение'
- assert (v1 < 'fdsfd') == 'Невозможно выполнить сравнение'
- assert (v1 == 'fdsfd') == 'Невозможно выполнить сравнение'
- assert (v1 == [1, 2]) == 'Невозможно выполнить сравнение'
- assert (v1 < [1, 2]) == 'Невозможно выполнить сравнение'
- print('Good')
- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- @total_ordering
- class Account:
- def __init__(self, balance):
- self.balance = balance
- def __eq__(self, other):
- return self.balance == other.balance
-
- def __lt__(self, other):
- return self.balance < other.balance
-
- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- @total_ordering
- class Rectangle:
- def __init__(self, width, height):
- self.width = width
- self.height = height
- @property
- def area(self):
- return self.width * self.height
-
- def __eq__(self, other):
- if isinstance(other, Rectangle):
- return self.area == other.area
- if isinstance(other, (int, float)):
- return self.area == other
-
- def __lt__(self, other):
- if isinstance(other, Rectangle):
- return self.area < other.area
- if isinstance(other, (int, float)):
- return self.area < other
- def main():
- test_1()
- if __name__ == '__main__':
- main()
|