How to use __getattribute__ to access a class attribute?

Shalabh Chaturvedi shalabh at cafepy.com
Mon Mar 1 23:33:59 CET 2004


Ruud de Jong wrote:
> Shalabh Chaturvedi schreef:
> 
>> Ruud de Jong wrote:
>>
>>> 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.
>>
>>
>>
>> If what you're trying to do is get C.a (where C is the class and a is 
>> the name of the staticmethod) but all you have is the class C and a 
>> string mname = "a", then just getattr(C, mname) should work. Generally 
>> this works for any attribute access where you have the attribute name 
>> in another variable.
> 
> 
> Erh, hmm, rrriight... Built-in functions. <blush/>
> Completely forgot about that one -- too focussed
> on trying to do everything with object methods and such.
> I really need to pay more attention to those built-in functions.
> 
> Well, that solves my immediate problem.
> I knew there had to be a simple solution :-)
> 
>>
>> Another way to get the naked function, which also works for 
>> classmethods, is to do C.__dict__['a']. See comments below that 
>> explain what you see.
> 
> 
> Well, that's not true, at least not on my system (XP, Python 2.3.3):
> 
>  >>> class C(object):
>     def a():
>         print "static method a"
>     a = staticmethod(a)
> 
>     
>  >>> C.__dict__['a']
> <staticmethod object at 0x00AADD10>
> 
>  > [snipped]

Sorry, my mistake. In fact it doesn't work for even classmethods. Only 
for functions.

>> To repeat the same experiment, you should call 
>> type(C).__getattribute__(C, 'a'). Note that in this case C *has* its 
>> own __getattribute__ attribute (which is meant for instances of C, not 
>> C itself). 
> 
> 
> C did not have its own __getattribute__ method. It inherited it
> from object.

True. Left out a little bit of information there (for brevity).

> I still find this whole thing slightly ambiguous.
> A class C is itself an object, an instance of 'type',
> just as x = C() leads to x being an instance of class C.
> But x.__getattribute__ and C.__getattribute__ return
> different objects.

Only if you didn't first do x.__getattribute___ = None <wink>. then 
x.__getattribute__ doesn't even return anything. x.__getattribute__ is 
never meant to be called. It is only called on /type/ objects. If you 
want to get an attribute on obj, you call __getattribute__ on type(obj). 
(Well that's what Python does, you can just use getattr(obj, 'attr')).

>> In fact you do this later, and it works. Hmm, at first glance I'd 
>> expect what you do above to return an exception if passed C instead of 
>> an instance of C (like any other well behaved method). I don't know 
>> why that doesn't happen.
> 
> 
> I would also have expected an exception. The strange thing, as I see
> it, is that x.__getattribute__ and type(C).__getattribute__ both give 
> the correct result, but that C.__getattribute__ *almost* gives the
> correct result, but stops at calling the __get__ function on the
> desciptor object.

What C.__getattribute__ doesn't do (maybe it should?) is to check that 
the first argument is an instance of C, or at least an instance of 
object. I'm just guessing here, but if it continues with the default 
mechanism of __getattribute__, it is going to get the staticmethod object.

> 
> Anyway, now that you've kindly reminded me of the existance of getattr,
> I'll not spend any more time trying to understand this.
> 
> Thanks,
> 
> Ruud
> 






More information about the Python-list mailing list