Простой Python. Современный стиль программирования (Любанович) - страница 95

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

Когда лучше использовать классы и объекты, а когда — модули

Рассмотрим несколько рекомендаций, которые помогут вам понять, где лучше разместить свой код — в классе или в модуле.

• Объекты наиболее полезны, когда вам нужно иметь некоторое количество отдельных экземпляров с одинаковым поведением (методами), но различающихся внутренним состоянием (атрибутами).