Steven Bethard said:
Of if you only want to deal with the case where the attribute doesn't
exist, you can use getattr, which gets called when the attribute can't
be found anywhere else:
py> class DefaultAttr(object):
... def __init__(self, default):
... self.default = default
... def __getattr__(self, name):
... return self.default
...
py> x = DefaultAttr(99)
py> x.a
99
py> x.a = 10
py> x.a
10
This is a good approach, but it's fragile regarding specialnames.
.... def __init__(self, default): self.default = default
.... def __getattr__(self, name): return self.default
.... Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/local/lib/python2.4/copy.py", line 87, in copy
rv = reductor(2)
TypeError: 'int' object is not callable
There are many more, worse example for classic classes, but even in
newstyle classes you must consider that once in a while a system routine
will try a getattr(someinst, '__aspecialname__', None) or the like --
and your class is making its instances claim to have ANY special name
that may be introspected for in this way. This can be a pernicious lie,
since your class in fact has no idea whatsoever what that specialname
and the corresponding value might be for.
It's HIGHLY advisable to have your __getattr__ methods raise
AttributeError for any requested name that starts and ends with double
underscores, possibly with some specific and specifically designed
exceptions.
Alex