How to use __getattribute__ to access a class attribute?

Ruud de Jong ruud.de.jong at consunet.nl
Sun Feb 29 16:46:17 EST 2004


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