[Из песочницы] Управление доступом к атрибутам класса в питоне
В этой заметке я хотел бы привести краткое описание методов регулирования доступа к атрибутам класса в питоне с помощью декораторов и с помощью присвоения специальным образом имен атрибутам в соответсвии с хорошим стилем программирования, описанным в PEP 8 . Статья написана на основе обсуждений данной темы на StackOverflow.com, нескольких мануалов и личного опыта автора. Занимаясь написанием программ, выполняющие научные расчеты, я перешел с c++ на питон, чтобы использовать всю мощь библиотек, к которым относятся numpy, scipy, matplotlib, pyquante и прочие, распространяющиеся под свободной лицензией и находящихся в избытке на github. Однако, на начальном этапе такого перехода у меня возник дискомфорт, связанный с отсутствием таких привычных в с++ модификаторов доступа, как privat, public и protected, а также методов get () и set (), что и побудило меня написать эту заметку. На StackOverflow первое, что бросается в глаза при обсуждении отсутствия модификаторов доступа в питоне, — это всеобщее согласие с большой долей ответственности разработчика при написании кода, которая побуждает его соблюдать хороший стиль программирования, описанный в PEP 8 . Проблема заключается в том, что в питоне всегда можно получить доступ к любому атрибуту любого класса, однако, согласно хорошему стилю, такой доступ пользователями библиотеки классов должен быть осуществлен не прямо, а с помощью некоторого интерфейса и только там, где это нужно и предусмотрено разработчиком. Рассмотрим, например, класс, содержащий один атрибут attr: class MyClass: def __init__(self,**kw): self.attr=0 Существует очевидная возможность доступа к атрибуту напрямую после создания объекта класса: a=Class () a.attr Этим способом обращения лучше не злоупотреблять. Для того, чтобы имитировать наличие модификатора доступа privat, можно использовать подчеркивание в начале всех имен атрибутов: class MyClass: def __init__(self,**kw): self._attr=0 Конечно, в этом случае к атрибуту можно обратиться извне класса как: a._attr Но каждый раз видя этот код вы будете знать, что: а) осуществляется обращения к атрибуту объекта, а и б) ваш код не соответствует хорошему стилю программирования, поскольку атрибут этого класса с таким именем не предусматривает, что к нему будут обращаться вне определения класса. Если все же есть необходимость предоставить пользователю доступ к атрибуту данного класса, лучше использовать декоратор @property. Например: class MyClass: def __init__(self,**kw): self.attr=0
@property def attr (self): return self._attr Читать дальше →