As you most likely are aware of the correct method to add properties would be to use:
@property
def silly(self):
return self._silly
@silly.setter:
def silly(self, value):
self._silly = value
But this requires new style classes, that is that somewhere in the chain there is supposed to be a class ParentClass(object):
. The similar option of using silly = property(get_silly, set_silly)
has the same requirement.
However, there is another option, and that is to use a corresponding private variable, like self._silly
, and override the __getattr__
and __setattr__
methods:
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
Notice how __getattr__
will be called after checking for other attributes, but that __setattr__
is called before checking for other attributes. Therefore the former can and should raise an error if not an accepted attribute, and the latter should set the attribute. Do not use self._silly = value
within __setattr__
as that would cause infinite recursion.
Also note that since we're dealing with old style classes here, you should actually use the dict method, and not the newer baseclass.__setattr__(self, attr, value)
, see docs. A similar __delattr__()
does also exist, if you want it.
Using this code, you can now do stuff like:
i_am = Silly()
i_am.silly = 'No, I'm clever'
print i_am.silly