How to use __getattribute__ to access a class attribute?

Chris feb04.20.netman at spamgourmet.com
Sun Feb 29 18:41:44 EST 2004


Perhaps it might be easier if you made your own static method object:

>>> class MyStaticMethod(object):
...     def __call__(self):
...         print "static method a"
...      def __get__(self, cls, inst):
...         return self.__call__
...
>>> class C(object):
...     a = MyStaticMethod()
>>> C.a
<bound method MyStaticMethod.__call__ of <__main__.MyStaticMethod object at
0x00E57390>>
>>> C.a()
static method a
>>> C.__getattribute__(C,'a')
<__main__.MyStaticMethod object at 0x00E57390>
>>> C.__getattribute__(C,'a')()
static method a
>>> c = C()
>>> c.a()
static method a
>>> C.__getattribute__(c,'a')
<bound method MyStaticMethod.__call__ of <__main__.MyStaticMethod object at
0x00E57390>>
>>> C.__getattribute__(c,'a')()
static method a

As far as your question goes, __getattribute__ is following the "... should
return the (computed) attribute value" rule for retrieving the static method
object... unfortunatly the calculated value in this case is a reference to
the static method object rather then the __get__ method bound to the static
method object.

HTH

Chris

"Ruud de Jong" <ruud.de.jong at consunet.nl> wrote in message
news:40425d1b$0$41761$5fc3050 at dreader2.news.tiscali.nl...
> I have the situation where I need to construct the name
> of a static method, and then retrieve the corresponding
> function from a class object.
>
> I thought I could just use __getattribute__ for this purpose.
> This works fine if I already have an instantiation of the class,
> but not when I try this on the class object directly.
>
> A bare bones example:
>
>  >>> class C(object):
> def a():
> print "static method a"
> a = staticmethod(a)
>
> It works for a instantiation of class C:
>
>  >>> x = C()
>  >>> x.a
> <function a at 0x00A981B0>
>  >>> x.__getattribute__('a')
> <function a at 0x00A981B0>
>  >>> x.__getattribute__('a')()
> static method a
>
> But for the class object it works differently:
>
>  >>> C.a
> <function a at 0x00A981B0>
>  >>> C.__getattribute__(C,'a')
> <staticmethod object at 0x00AC6A10>
>  >>> C.a()
> static method a
>  >>> C.__getattribute__(C,'a')()
>
> Traceback (most recent call last):
>    File "<pyshell#219>", line 1, in -toplevel-
>      C.__getattribute__(C,'a')()
> TypeError: 'staticmethod' object is not callable
>
> After some experimentation and documentation searching,
> I found that to get at the actual function, the __get__
> method for the staticmethod descriptor must be called:
>
>  >>> C.__getattribute__(C,'a').__get__(None, C)
> <function a at 0x00A981B0>
>  >>> C.__getattribute__(C,'a').__get__(None, C)()
> static method a
>
> If I use an class instance as the first argument
> it works OK. But I ran into this problem when I tried
> to use __getattribute__ in the __new__ function of a class
> -- there is no class instance yet at that point,
> and calling C() there leads to infinite recursion.
>
> Another variant that worked is to call __getattribute__
> on the metaclass:
>
>  >>> type(C).__getattribute__(C,'a')
> <function a at 0x00A981B0>
>  >>> type(C).__getattribute__(C,'a')()
> static method a
>
> But according to section 3.3.2.1 of the Language Reference
> (More attribute access for new-style classes),
> __getattribute__ "... should return the (computed) attribute value".
> This could be interpreted to say that __getattribute__ should
> return the function, not the staticmethod object.
>
> Is there a reason for this difference in behavior?
>





More information about the Python-list mailing list