changing __getattr__ dynamically

Peter Otten __peter__ at web.de
Wed Jul 28 06:05:54 EDT 2004


Dan Bentley wrote:

> class foo(object):
>   def __getattr__(self, name):
>     return 42
> 
> def e(self, name):
>   return 2.7
> 
> bar = foo()
> print bar.baz
> bar.__getattr__ = e
> print bar.baz
> 
> I'd expect this to print:
> 42
> 2.7
> 
> But instead it prints:
> 42
> 42
> 
> Is there a way to change the actual __getattr__ used at runtime?

One more note - the above wouldn't work for "normal" methods, too:

>>> class foo(object):
...     def e(self): return "in class"
...
>>> def ee(self):
...     return "in instance"
...
>>> bar = foo()
>>> bar.e()
'in class'
>>> bar.e = ee
>>> bar.e()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: ee() takes exactly 1 argument (0 given)

I.e. if you assign a function to an instance attribute, self will not be
passed implicitely. Instead

>>> import new
>>> bar.e = new.instancemethod(ee, bar)
>>> bar.e()
'in instance'
>>> foo().e()
'in class'

will achieve the desired specialization for the modified foo instance while
preserving the standard behaviour.

Peter




More information about the Python-list mailing list