В языке 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 можно организовать доступ к любым (даже несуществующим) атрибутам, обрабатывая запрос на доступ к атрибуту группой специальных методов:
Следующий небольшой пример демонстрирует все перечисленные моменты. В этом примере из словаря создается объект, именами атрибутов которого будут ключи словаря, а значениями — значения из словаря по заданным ключам:
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