Python/Объектно-ориентированное программирование на Python: различия между версиями
Содержимое удалено Содержимое добавлено
→Конструктор и деструктор: оформление |
→Инкапсуляция и доступ к свойствам: оформление |
||
Строка 129:
Сокрытие информации о внутреннем устройстве объекта выполняется в Python на уровне соглашения между программистами о том, какие атрибуты относятся к общедоступному интерфейсу класса, а какие — к его внутренней реализации. Одиночное подчеркивание в начале имени атрибута говорит о том, что атрибут не предназначен для использования вне методов класса (или вне функций и классов модуля), однако, атрибут все-таки доступен по этому имени. Два подчеркивания в начале имени дают несколько большую защиту: атрибут перестает быть доступен по этому имени. Последнее используется достаточно редко.
Есть существенное отличие между такими атрибутами и личными (private) членами класса в таких языках как [[C++]] или [[Java]]: атрибут остается доступным, но под именем вида <code>_ИмяКласса__ИмяАтрибута</code>, а при каждом обращении <code>Python</code> будет модифицировать имя в зависимости от того, через экземпляр какого класса происходит обращение к атрибуту. Таким образом, родительский и дочерний классы могут иметь атрибут с именем, например, «__f», но не будут мешать друг другу.
<source lang="python">
>>> class parent(object):
Строка 158 ⟶ 154 :
</source>
Особым случаем является наличие двух подчеркиваний в начале и в конце имени атрибута. Они используются для специальных свойств и функций класса (например, для перегрузки операции). Такие атрибуты доступны по своему имени, но их использование зарезервировано для специальных атрибутов, изменяющих поведение объекта.
Доступ к атрибуту может быть как прямой:
<source lang="python">
class A(object):
Строка 176 ⟶ 168 :
Так и с использованием свойств с заданными методами для получения, установки и удаления атрибута:
<source lang="python">
class A(object):
def __init__(self, x):
self._x = x
def getx(self): # метод для получения значения
return self._x
def setx(self, value): # присваивания нового значения
self._x = value
def delx(self): # удаления атрибута
del self._x
x = property(getx, setx, delx, "Свойство x") # определяем x как свойство
Строка 196 ⟶ 191 :
Разумеется, первый способ хорош только если значение атрибута является атомарной операцией по изменению состояния объекта. Если же это не так, то второй способ позволит выполнить все необходимые действия в соответствующих методах.
Существуют два способа централизованно контролировать доступ к атрибутам. Первый основан на перегрузке методов <code>__getattr__()</code>, <code>__setattr__()</code>, <code>__delattr__()</code>, а второй — метода <code>__getattribute__()</code> . Второй метод помогает управлять чтением уже существующих атрибутов.
Эти способы позволяют организовать полностью динамический доступ к атрибутам объекта или, что используется очень часто, имитации несуществующих атрибутов. По такому принципу функционируют, например, все системы [[Remote Procedure Call|RPC]] для Python, имитируя методы и свойства, реально существующие на удаленном сервере.
|