Python/Объектно-ориентированное программирование на Python: различия между версиями

Содержимое удалено Содержимое добавлено
Строка 129:
 
Сокрытие информации о внутреннем устройстве объекта выполняется в Python на уровне соглашения между программистами о том, какие атрибуты относятся к общедоступному интерфейсу класса, а какие — к его внутренней реализации. Одиночное подчеркивание в начале имени атрибута говорит о том, что атрибут не предназначен для использования вне методов класса (или вне функций и классов модуля), однако, атрибут все-таки доступен по этому имени. Два подчеркивания в начале имени дают несколько большую защиту: атрибут перестает быть доступен по этому имени. Последнее используется достаточно редко.
Есть существенное отличие между такими атрибутами и личными (private) членами класса в таких
языках как [[C++]] или [[Java]]: атрибут остается доступным, но под именем вида
<code>_ИмяКласса__ИмяАтрибута</code>, а при каждом обращении <code>Python</code> будет модифицировать имя в зависимости
от того, через экземпляр какого класса происходит обращение к атрибуту. Таким образом, родительский и дочерний
классы могут иметь атрибут с именем, например, «__f», но не будут мешать друг другу.
 
Есть существенное отличие между такими атрибутами и личными (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> . Второй метод помогает управлять чтением уже существующих атрибутов.
 
методов <code>__getattr__()</code>, <code>__setattr__()</code>, <code>__delattr__()</code>,
а второй — метода <code>__getattribute__()</code> . Второй метод помогает управлять чтением уже существующих атрибутов.
Эти способы позволяют организовать полностью динамический доступ к атрибутам объекта или, что используется очень часто, имитации несуществующих атрибутов. По такому принципу функционируют, например, все системы [[Remote Procedure Call|RPC]] для Python, имитируя методы и свойства, реально существующие на удаленном сервере.