Modifying an instances dict to change attribute lookup

Alex Martelli aleaxit at yahoo.com
Mon Feb 20 11:30:26 EST 2006


jslowery at gmail.com <jslowery at gmail.com> wrote:
   ...
> c = C()
> c.x = 1
> assert c.__dict__.__getitem__('x') == c.x
> 
> Could someone please tell me why the first example using a customized
> dict does not perform as advertised?

Because Python's __getattribute__ is currently not EXACTLY as you
imagine it to be, but slightly different, say something like:
    dict.__getitem__(c, 'x')
at the crucial step rather than c.__getitem__.  More generally, when (on
any type or newstyle class -- oldstyle legacy classes are different) a
special method gets implicitly invoked, it's invoked on the type, not on
the instance (no per-instance overriding in this case); and, for speed,
many internal dict lookups do "dict.__getitem__(obj,name)" rather than
"type(obj).__getitem__(obj, name)".

The documented way to do what you want in Python is by overriding
__getattr__ (which gets called when other normal lookup procedures fail
and would, absent __getattr__, raise AttributeError), not by trying to
install as the __dict__ something whose type isn't exactly __dict__.
Other approaches may work, but they depend on implementation accidents
which are liable to change with every passing breeze.


Alex



More information about the Python-list mailing list