__getattr__ Confusion
Saul Spatz
saul.spatz at gmail.com
Mon Feb 4 08:44:48 EST 2013
On Sunday, February 3, 2013 10:35:30 PM UTC-6, Steven D'Aprano wrote:
> 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
>
> solution.
>
>
>
>
>
> > 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.
>
>
>
>
>
>
>
> --
>
> Steven
Thanks. The class versus instance lookup explains it.
I didn't mean that python crashed, but that my app did.
Now I have another question. If dunder methods are looked up only in the class, not the instance, why did defining __nonzero__ the way I did work? Shouldn't I have had to define it with a def? Is __nonzero__ a special case?
More information about the Python-list
mailing list