168
Глава 6. Ой-ой-ой: объекты и классы
А вот и самое интересное — мы можем изменить значение атрибута radius в лю-
бой момент и свойство diameter будет рассчитано на основе текущего значения
атрибута radius:
>>> c.radius = 7
>>> c.diameter
14
Если вы не укажете сеттер для атрибута, то не сможете устанавливать его зна-
чение извне. Это удобно для атрибутов, которые должны быть доступны только
для чтения:
>>> c.diameter = 20
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
У использования свойств вместо непосредственного доступа к атрибутам име-
ется еще одно преимущество: если вы измените определение атрибута, вам нужно
будет поправить только код внутри определения класса вместо того, чтобы править
все вызовы.
Искажение имен для безопасности
В примере с классом Duck из предыдущего раздела мы вызывали наш (не полно-
стью) скрытый атрибут hidden_name. Python предлагает соглашения по именованию
для атрибутов, которые не должны быть видимы за пределами определения их
классов: имена начинаются с двух нижних подчеркиваний (__).
Переименуем атрибут hidden_name в __name, как показано здесь:
>>> class Duck():
... def __init__(self, input_name):
... self.__name = input_name
… @property
... def name(self):
... print('inside the getter')
... return self.__name
... @name.setter
... def name(self, input_name):
... print('inside the setter')
... self.__name = input_name
...
Теперь проверим, работает ли все как полагается:
>>> fowl = Duck('Howard')
>>> fowl.name
inside the getter
Типы методов
169
'Howard'
>>> fowl.name = 'Donald'
inside the setter
>>> fowl.name
inside the getter
'Donald'