Язык программирования Python.

Доступ к свойствам.

В языке Python не считается зазорным получить доступ к некоторому атрибуту (не методу) напрямую, если, конечно, этот атрибут описан в документации как часть интерфейса класса. Такие атрибуты называются свойствами (properties). В других языках программирования принято для доступа к свойствам создавать специальные методы (вместо того чтобы напрямую обращаться к общедоступным членам–данным). В Python достаточно использовать ссылку на атрибут, если свойство ни на что в объекте не влияет (то есть другие объекты могут его произвольно менять). Если же свойство менее тривиально и требует каких–то действий в самом объекте, его можно описать как свойство (пример взят из документации к Python):

Class C(object):

 def getx(self): return self.__x.

 def setx(self, value): self.__x = value.

 def delx(self): del self.__x.

 x = property(getx, setx, delx, "I'm the 'x' property.").

Синтаксически доступ к свойству x будет обычной ссылкой на атрибут:

>>> c = C().

>>> c.x = 1.

>>> print c.x.

1.

>>> del c.x.

А на самом деле будут вызываться соответствующие методы: setx(), getx(), delx().

Следует отметить, что в экземпляре класса в Python можно организовать доступ к любым (даже несуществующим) атрибутам, обрабатывая запрос на доступ к атрибуту группой специальных методов:

__getattr__(self, name) Этот метод объекта вызывается в том случае, если атрибут не найден другим способом (его нет в данном экземпляре или в дереве классов). Здесь name — имя атрибута. Метод должен вычислить значение атрибута либо возбудить исключение AttributeError. Для получения полного контроля над атрибутами в «новых» классах (то есть потомках object) используйте метод __getattribute__().
__setattr__(self, name, value) Этот метод вызывается при присваивании значения некоторому атрибуту. В отличие от __getattr__(), метод всегда вызывается, а не только тогда, когда атрибут может быть найден в экземпляре класса, поэтому нужно с осторожностью присваивать значения атрибутам внутри этого метода: это может вызвать рекурсию. Для присваивания значений атрибутов предпочтительнее присваивать словарю __dict__: self.__dict__[name] = value или (для «новых» классов) — обращение к __setattr__() базового класса: object.__setattr__(self, name, value).
__delattr__(self, name) Как можно догадаться из названия, этот метод служит для удаления атрибута.

Следующий небольшой пример демонстрирует все перечисленные моменты. В этом примере из словаря создается объект, именами атрибутов которого будут ключи словаря, а значениями — значения из словаря по заданным ключам:

Class AttDict(object):

 def __init__(self, dict=None):

  object.__setattr__(self, '_selfdict', dict or {}).

 def __getattr__(self, name):

  if self._selfdict.has_key(name):

   return self._selfdict[name].

  else:

   raise AttributeError.

 def __setattr__(self, name, value):

  if name[0] != '_':

   self._selfdict[name] = value.

  else:

   raise AttributeError.

 def __delattr__(self, name):

  if name[0] != '_' and self._selfdict.has_key(name):

   del self._selfdict[name].

Ad = AttDict({'a': 1, 'b': 10, 'c': '123'}).

Print ad.a, ad.b, ad.c.

Ad.d = 512.

Print ad.d.