>>> second = Word('HA')
>>> third = Word('eh')
>>> first == second
True
>>> first == third
False
Магия! Все, что нам было нужно, — указать особое имя метода для проверки на равенство __eq__(). В табл. 6.1 и 6.2 приведены имена самых полезных магических методов.
__eq__(self, other) | self == other |
__ne__(self, other) | self!= other |
__lt__(self, other) | self < other |
__gt__(self, other) | self > other |
__le__(self, other) | self <= other |
__ge__(self, other) | self >= other |
Таблица 6.2. Магические методы для вычислений
__add__(self, other) | self + other |
__sub__(self, other) | self — other |
__mul__(self, other) | self * other |
__floordiv__(self, other) | self // other |
__truediv__(self, other) | self / other |
__mod__(self, other) | self % other |
__pow__(self, other) | self ** other |
Не обязательно использовать математические операторы вроде + (магический метод __add__()) и — (магический метод __sub__()) только для работы с числами. Например, строковые объекты используют + для конкатенации и * для дуплицирования. Существует множество других методов, задокументированных онлайн по адресу http://bit.ly/pydocs-smn. Наиболее распространенные из них представлены в табл. 6.3.
__str__(self) | str(self) |
__repr__(self) | repr(self) |
__len__(self) | len(self) |
Вы можете обнаружить, что, помимо __init__(), часто пользуетесь методом __str__(). Он нужен для того, чтобы выводить данные на экран. Этот метод используется методами print(), str() и строками форматирования, о которых вы можете прочитать в главе 7. Интерактивный интерпретатор применяет функцию __repr__() для того, чтобы выводить на экран переменные. Если вы не определите хотя бы один из этих методов, то увидите на экране ваш объект, преобразованный в строку по умолчанию:
>>> first = Word('ha')
>>> first
<__main__.Word object at 0x1006ba3d0>
>>> print(first)
<__main__.Word object at 0x1006ba3d0>
Добавим в класс Word методы __str__() и __repr__(), чтобы он лучше смотрелся:
>>> class Word():
…·····def __init__(self, text):
…·········self.text = text
…·····def __eq__(self, word2):
…·········return self.text.lower() == word2.text.lower()
…·····def __str__(self):
…·········return self.text
…·····def __repr__(self):
…·········return 'Word("'··self.text··'")'
…
>>> first = Word('ha')
>>> first··········# используется __repr__
Word("ha")
>>> print(first)···# используется __str__
ha
Чтобы узнать о других особых методах, обратитесь к документации Python (http://bit.ly/pydocs-smn).
Наследование может сослужить хорошую службу, если вам нужно создать класс-потомок, который ведет себя как родительский класс бо́льшую часть времени (когда потомок является предком). Возможность создавать иерархии наследования довольно заманчива, но иногда
>>> class Bill():
…·····def __init__(self, description):
…·········self.description = description
…
>>> class Tail():
…·····def __init__(self, length):
…·········self.length = length
…
>>> class Duck():
…·····def __init__(self, bill, tail):
…·········self.bill = bill
…·········self.tail = tail
…·····def about(self):
…·········print('This duck has a', bill.description, 'bill and a',
··················tail.length, 'tail')
…