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).
Наследование может сослужить хорошую службу, если вам нужно создать класс-потомок, который ведет себя как родительский класс бо́льшую часть времени (когда потомок является предком). Возможность создавать иерархии наследования довольно заманчива, но иногда композиция или агрегирование (когда x имеет y) имеет больше смысла. Утка является птицей, но имеет хвост. Хвост не похож на утку, он является частью утки. В следующем примере создадим объекты bill и tail и предоставим их новому объекту duck:
>>>> 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')
>…
>>>> tail = Tail('long')
>>>> bill = Bill('wide orange')
>>>> duck = Duck(bill, tail)
>>>> duck.about()
>This duck has a wide orange bill and a long tail
Когда лучше использовать классы и объекты, а когда — модули
Рассмотрим несколько рекомендаций, которые помогут вам понять, где лучше разместить свой код — в классе или в модуле.
• Объекты наиболее полезны, когда вам нужно иметь некоторое количество отдельных экземпляров с одинаковым поведением (методами), но различающихся внутренним состоянием (атрибутами).