470,614 Members | 1,488 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,614 developers. It's quick & easy.

Why doesnt __getattr__ with decorator dont call __get_method in decorator

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?

Example:
class decoratorTest(object):
def __init__(self, func):
self.func = func

def __get__(self, instance, cls=None):
print "__get__", instance
self.instance = instance
return self

def __call__(self, *args, **kwds):
return self.func(self.instance, *args, **kwds)

class MyClass1(object):

@decoratorTest
def decoratorTestFunc(self):
print "hello1"

@decoratorTest
def __getattr__(self,name):
print "hello2"
a = MyClass1()
a.decoratorTestFunc() # This works since the __get__ method is called
and the instance is retreived
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'

Mar 28 '07 #1
5 2202
glomde <tb****@yahoo.comwrote:
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...
Alex
Mar 28 '07 #2
On Mar 28, 4:47 pm, a...@mac.com (Alex Martelli) wrote:
glomde <tbr...@yahoo.comwrote:
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...

Alex
I was using 2.4 but I downloaded and installed ActivePython2.5.0.0 and
for I get the same message as in my original email.
What python version do you use more exactly?

/T


Mar 28 '07 #3
On Mar 28, 8:28 am, "glomde" <tbr...@yahoo.comwrote:
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?
All you have to do is decorator should methods write be for reason it
works with class __getattr__ in!

Mar 28 '07 #4
On Mar 28, 3:47 pm, a...@mac.com (Alex Martelli) wrote:
glomde <tbr...@yahoo.comwrote:
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

Mar 28 '07 #5
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
So is this a python bug? I assumed it was seen as function but dont
understand why it is like this. But interesting that if you call
__getattr__ explicitly it works.

Intuitevely I would assumet that the same route should be followed
in both case.

Maybe it is because __getattr__ is called only when you have an
exception.

/T

Mar 29 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Greg Brunet | last post: by
30 posts views Thread by Ron_Adam | last post: by
22 posts views Thread by Ron_Adam | last post: by
13 posts views Thread by Pelmen | last post: by
13 posts views Thread by Lad | last post: by
6 posts views Thread by Erik Johnson | last post: by
4 posts views Thread by thomas.karolski | last post: by
4 posts views Thread by Enrico | last post: by
2 posts views Thread by mwojc | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.