__getattr__ Confusion

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Feb 4 05:35:30 CET 2013

On Sun, 03 Feb 2013 17:08:47 -0800, Saul Spatz wrote:

> I don't understand what's going on at all.  Can't I dynamically define
> __getattr__?  How should I go about it?  

Special "dunder" methods (DoubleUNDERscore) are looked up only on the 
class, not on instances. That means that if you try to dynamically 
provide a dunder method by assigning it to an instance, say with:

    self.__nonzero__ = lambda self: True

it will *not* be automatically used by Python. The only way to 
dynamically add dunder methods is to add them to the class, but of course 
that means that all instances see the same method.

In your case, you try doing this inside the __init__:

    self.__getattr__ = lambda x, name: getattr(self.canvas, name)

Why not just define a __getattr__ method the normal way? In your class, 
define a method:

    def __getattr__(self, name):
        return getattr(self.canvas, name)

This technique is called automatic delegation.

Even if this does not quite do what you are trying to do, you will 
eliminate one major stumbling block and be that much closer to a working 

> By the way, another thing that
> didn't work was calling the method delegate instead of __getattr__. 
> Then after the constructor call, I wrote self.__getattr__ =
> self.delegate.  This crashed as before on self.create_text.

It is pointless to tell us that Python "crashed" if you don't show us 
*exactly* what you did, by copying and pasting the *actual* code, 
complete with the full traceback. Otherwise we are just guessing what you 
did and what error you saw.

I'm pretty confident that Python didn't "crash", in the commonly accepted 
meaning of the word meaning a core dump or equivalent. I'm guessing you 
meant that Python raised a perfectly normal exception, like

Traceback (most recent call last):
NameError: name 'self' is not defined

If you pay attention to the exception messages that Python prints for 
you, you will not only find it easier to debug your code, but you can 
also ask more sensible questions using accepted terminology.


More information about the Python-list mailing list