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

зачастую приходится писать геттеры и сеттеры, чтобы считать и записать значе-

ния таких атрибутов.

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

открытыми, а от вас ожидается примерное поведение. Если прямой доступ к атри-

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

Но сделайте это более характерным для Python способом — используйте свойства.

В этом примере мы определим класс Duck, имеющий один атрибут hidden_name.

(В следующем разделе я покажу вам более удачный способ именовать атрибуты,

которые вы хотите оставить закрытыми.) Мы не хотим, чтобы люди обращались

к атрибуту напрямую, поэтому определим два метода: геттер (get_name()) и сеттер

(set_name()). Я добавил выражение print() в каждый из них, чтобы показать момент

его вызова. Наконец, мы определим эти методы как свойства атрибута name:

>>> class Duck():

... def __init__(self, input_name):

... self.hidden_name = input_name

... def get_name(self):

... print('inside the getter')

... return self.hidden_name

... def set_name(self, input_name):

... print('inside the setter')

... self.hidden_name = input_name

... name = property(get_name, set_name)

166

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

Новые методы действуют как обычные геттеры и сеттеры до последней строки,

где они указываются как свойства атрибута name. Первый аргумент функции

property() — это геттер, а второй — это сеттер. Теперь, когда вы обращаетесь

к атрибуту name любого объекта Duck, вызывается метод get_name(), который воз-

вращает его:

>>> fowl = Duck('Howard')

>>> fowl.name

inside the getter

'Howard'

Вы все еще можете вызвать метод get_name() непосредственно, как обычный

геттер:

>>> fowl.get_name()

inside the getter

'Howard'

Когда вы присваиваете значение атрибуту name, вызывается метод set_name():

>>> fowl.name = 'Daffy'

inside the setter

>>> fowl.name

inside the getter

'Daffy'

Метод set_name() вы также можете вызвать непосредственно:

>>> fowl.set_name('Daffy')

inside the setter

>>> fowl.name

inside the getter

'Daffy'