Why doesnt __getattr__ with decorator dont call __get_method in decorator

Arnaud Delobelle arnodel at googlemail.com
Wed Mar 28 13:18:55 EDT 2007


On Mar 28, 3:47 pm, a... at mac.com (Alex Martelli) wrote:
> glomde <tbr... at yahoo.com> wrote:
> > Hi,
>
> > I tried to write a decorator for that should be for methods but for
> > some reasons
> > it doens seem to work when you try to do it on the __getattr__ method
> > in a class.
> > Could anybody give some hints why this is?
> ...
> > a.test # This doesnt call the __get__ !!!
>
> > Output
> > __get__ <__main__.MyClass1 object at 0x4012baac>
> > hello1
> > Traceback (most recent call last):
> >   File "/home/tonib/test.py", line 27, in ?
> >     a.test
> >   File "/home/tonib/test.py", line 12, in __call__
> >     return self.func(self.instance, *args, **kwds)
> > AttributeError: 'decoratorTest' object has no attribute 'instance'
>
> What Python release are you using?  With Python 2.5, your code gives me
> instead:
>
> >>> a.test
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "a.py", line 11, in __call__
>     return self.func(self.instance, *args, **kwds)
> TypeError: __getattr__() takes exactly 2 arguments (3 given)
>
>
>
> so there would seem to be some "mis-alignment" wrt the problems you
> observe...

I get this error with python 2.4 when I do

a.__getattr__('test') # This sets the 'instance' attribute as __get__
is called
a.test # __get__ is not called but 'instance' is set

To get python to run the __get__ method I think you have to call
__getattr__ explicitly:
a.__getattr__('test')

If you do:
a.test
python follows a different routine: it checks for the existence of the
attribute, then check if there is a __getattr__ attribute. Now the
speculative bit: then I conjecture that python assumes that
__getattr__ is a function with two arguments and directly passes them
on to it.  Indeed

type(a).__dict__['__getattr__'](a, 'test')

seems to produce the same errors as a.test, whether the instance
attribute is set or not.
And this explain why there are too many arguments (error message
above).

--
Arnaud




More information about the Python-list mailing list