Why doesnt __getattr__ with decorator dont call __get_method in decorator

Discussion in 'Python' started by glomde, Mar 28, 2007.

  1. glomde

    glomde Guest

    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'
     
    glomde, Mar 28, 2007
    #1
    1. Advertising

  2. glomde <> 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...


    Alex
     
    Alex Martelli, Mar 28, 2007
    #2
    1. Advertising

  3. glomde

    glomde Guest

    On Mar 28, 4:47 pm, (Alex Martelli) wrote:
    > glomde <> 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...
    >
    > 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
     
    glomde, Mar 28, 2007
    #3
  4. glomde

    7stud Guest

    On Mar 28, 8:28 am, "glomde" <> 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?
    >


    All you have to do is decorator should methods write be for reason it
    works with class __getattr__ in!
     
    7stud, Mar 28, 2007
    #4
  5. On Mar 28, 3:47 pm, (Alex Martelli) wrote:
    > glomde <> 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
     
    Arnaud Delobelle, Mar 28, 2007
    #5
  6. glomde

    glomde Guest


    > 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
     
    glomde, Mar 29, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Pelmen
    Replies:
    13
    Views:
    487
    bruno at modulix
    Dec 15, 2005
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,071
    Smokey Grindel
    Dec 2, 2006
  3. Roc Zhou
    Replies:
    0
    Views:
    249
    Roc Zhou
    Jun 22, 2007
  4. Roc Zhou
    Replies:
    7
    Views:
    296
    Peter Otten
    Jun 22, 2007
  5. Replies:
    3
    Views:
    443
    alex23
    May 27, 2008
Loading...

Share This Page