how do i create such a thing?
Alex Martelli
aleaxit at yahoo.com
Mon Jan 31 08:16:38 EST 2005
Steven Bethard <steven.bethard at gmail.com> wrote:
> 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.
>>> class DefaultAttr(object):
... def __init__(self, default): self.default = default
... def __getattr__(self, name): return self.default
...
>>> import copy
>>> copy.copy(DefaultAttr(99))
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
More information about the Python-list
mailing list