Простой Python. современный стиль программирования - читать онлайн бесплатно полную версию книги . Страница 126

Выглядит хорошо. И вы не можете получить доступ к атрибуту __name:

>>> fowl.__name

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

AttributeError: 'Duck' object has no attribute '__name'

Это соглашение по именованию не делает атрибут закрытым, но Python иска-

жает имя для того, чтобы внешний код не наткнулся на него. Если вам любопытно

и вы никому не расскажете, я покажу вам, как будет выглядеть атрибут:

>>> fowl._Duck__name

'Donald'

Обратите внимание на то, что на экране не появилась надпись inside the getter.

Хотя эта защита не идеальна, искаженное имя отказывается случайно или наме-

ренно получать доступ к атрибуту.

Типы методов

Одни данные (атрибуты) и функции (методы) являются частью самого класса,

а другие — частью объектов, которые созданы на его основе.

Когда вы видите начальный аргумент self в методах внутри определения клас-

са, этот метод является методом экземпляра. Такие методы вы обычно пишете при

создании собственного класса. Первый параметр метода экземпляра — это self,

и Python передает объект методу, когда вы его вызываете.

В противоположность ему метод класса влияет на весь класс целиком. Любое

изменение, которое происходит с классом, влияет на все его объекты. Внутри опре-

деления класса декоратор @classmethod показывает, что следующая функция являет-

ся методом класса. Первым параметром метода также является сам класс. Согласно

традиции этот параметр называется cls, поскольку слово class является зарезер-

вированным и не может быть использовано здесь. Определим метод класса для А,

который будет подсчитывать количество созданных объектов:

>>> class A():

... count = 0

... def __init__(self):

... A.count += 1

... def exclaim(self):

... print("I'm an A!")

170

Глава 6. Ой-ой-ой: объекты и классы

... @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.

Третий тип методов не влияет ни на классы, ни на объекты: он находится внутри

класса только для удобства вместо того, чтобы располагаться где-то отдельно.