Как вы, скорее всего, знаете, правильный метод для добавления свойств будет использовать:
@property
def silly(self):
return self._silly
@silly.setter:
def silly(self, value):
self._silly = value
Но для этого нужны новые классы стилей, то есть где-то в цепочке должен бытьclass ParentClass(object):
.Аналогичная опция использования silly = property(get_silly, set_silly)
имеет такое же требование.
Однако существует другая опция, которая заключается в использовании соответствующей закрытой переменной, такой как self._silly
, и переопределении __getattr__
и __setattr__
методы:
def __getattr__(self, name):
"""Called _after_ looking in the normal places for name."""
if name == 'silly':
self._silly
else:
raise AttributeError(name)
def __setattr__(self, name, value):
"""Called _before_ looking in the normal places for name."""
if name == 'silly':
self.__dict__['_silly'] = value
else:
self.__dict__[name] = value
Обратите внимание, как __getattr__
будет вызываться после проверки других атрибутов, но что __setattr__
вызывается до проверки других атрибутов,Поэтому первый может и должен вызвать ошибку, если не принятый атрибут, а второй должен установить атрибут. не используйте self._silly = value
в __setattr__
, так как это приведет к бесконечной рекурсии.
Также обратите внимание, что, поскольку здесь мы имеем дело со старыми классами стилей, вам следует использовать метод dictи не новее baseclass.__setattr__(self, attr, value)
, см. документы .Аналогичный __delattr__()
также существует, если вы этого хотите.
Используя этот код, вы теперь можете делать такие вещи, как:
i_am = Silly()
i_am.silly = 'No, I'm clever'
print i_am.silly