>>>> 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.
Далее создадим несколько объектов: