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

>>>> class A():

>…·····count = 0

>…·····def __init__(self):

>…·········A.count += 1

>…·····def exclaim(self):

>…·········print("I'm an A!")

>…·····@classmethod

>…·····def kids(cls):

>…·········print("A has", cls.count, "little objects.")

>…

>>>>

>>>> easy_a = A()

>>>> breezy_a = A()

>>>> wheezy_a = A()

>>>> A.kids()

>A has 3 little objects.

Обратите внимание на то, что мы вызвали метод A.count (атрибут класса) вместо self.count (который является атрибутом объекта). В методе kids() мы использовали вызов cls.count, но с тем же успехом могли бы применять вызов A.count.

Третий тип методов не влияет ни на классы, ни на объекты: он находится внутри класса только для удобства вместо того, чтобы располагаться где-то отдельно. Это статический метод, перед которым располагается декоратор @staticmethod, не имеющий в качестве начального параметра ни self, ни класс class. Рассмотрим пример, который служит в качестве рекламы класса CoyoteWeapon:

>>>> class CoyoteWeapon():

>…·····@staticmethod

>…·····def commercial():

>…·········print('This CoyoteWeapon has been brought to you by Acme')

>…

>>>>

>>>> CoyoteWeapon.commercial()

>This CoyoteWeapon has been brought to you by Acme

Обратите внимание на то, что нам не нужно создавать объект класса CoyoteWeapon, чтобы получить доступ к этому методу. Это здорово.

Утиная типизация

В Python имеется также реализация полиморфизма — это значит, что одна операция может быть произведена над разными объектами независимо от их класса.

Используем уже знакомый нам инициализатор __init__() для всех трех классов Quote, но добавим две новые функции:

• who() возвращает значение сохраненной строки person;

• says() возвращает сохраненную строку words, имеющую особую пунктуацию.

Посмотрим на них в действии:

>>>> class Quote():

>…·····def __init__(self, person, words):

>…·········self.person = person

>…·········self.words = words

>…·····def who(self):

>…·········return self.person

>…·····def says(self):

>…·········return self.words + '.'

>…

>>>> class QuestionQuote(Quote):

>…······def says(self):

>…··········return self.words + '?'

>…

>>>> class ExclamationQuote(Quote):

>…······def says(self):

>…··········return self.words + '!'

>…

>>>>

Мы не меняли способ инициализации классов QuestionQuote и ExclamationQuote, поэтому не перегружали их методы __init__(). Далее Python автоматически вызывает метод __init__() родительского класса Quote, чтобы сохранить переменные объекта person и words. Поэтому мы можем получить доступ к атрибуту self.words в объектах, созданных с помощью подклассов QuestionQuote и ExclamationQuote.

Далее создадим несколько объектов: