|
@@ -0,0 +1,171 @@
|
|
|
|
+'''
|
|
|
|
+Операции сравнения и 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()
|