Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the exact rational behind getattribute in Python?

Tags:

python

I trid to run below sample code from python reference.

>>> class Meta(type):
...    def __getattribute__(*args):
...       print "Metaclass getattribute invoked"
...       return type.__getattribute__(*args)
...
>>> class C(object):
...     __metaclass__ = Meta
...     def __len__(self):
...         return 10
...     def __getattribute__(*args):
...         print "Class getattribute invoked"
...         return object.__getattribute__(*args)

Then I tested the below code:

In [16]: c = C()
class getattribute invoked
class getattribute invoked

In [17]: c
Class getattribute invoked
Class getattribute invoked
Out[17]: Class getattribute invoked
Metaclass getattribute invoked
Metaclass getattribute invoked
Metaclass getattribute invoked
Metaclass getattribute invoked
Metaclass getattribute invoked
Class getattribute invoked
Metaclass getattribute invoked
Metaclass getattribute invoked
Metaclass getattribute invoked
Metaclass getattribute invoked
<__main__.C at 0x29448d0>

Can anybody have a clear explanation on the output? I saw so many "Metaclass getattribute invoked" is displayed which means that the __getattribute__() is invoked many times.

like image 380
meng jue Avatar asked May 06 '26 09:05

meng jue


1 Answers

I did the same. Except printed the args:

In [2]: class Meta(type):
   ...:     def __getattribute__(*args):
   ...:         print args
   ...:         return type.__getattribute__(*args)
   ...:     

In [3]: class C(object):
   ...:     __metaclass__ = Meta
   ...:     def __len__(self):
   ...:         return 10
   ...:     def __getattribute__(*args):
   ...:         print args
   ...:         return object.__getattribute__(*args)

Got this result:

In [8]: c
(<__main__.C object at 0x104aeff10>, '__class__')
(<__main__.C object at 0x104aeff10>, '__class__')
Out[8]: (<__main__.C object at 0x104aeff10>, '__class__')
(<class '__main__.C'>, '__mro__')
(<class '__main__.C'>, '__mro__')
(<class '__main__.C'>, '__module__')
(<class '__main__.C'>, '__name__')
(<class '__main__.C'>, '__dict__')
(<__main__.C object at 0x104aeff10>, '__class__')
(<class '__main__.C'>, '__repr__')
(<class '__main__.C'>, '__class__')
(<class '__main__.C'>, '__module__')
(<class '__main__.C'>, '__name__')
<__main__.C at 0x104aeff10>

Pretty self-explanatory. First argument is object and second is attribute called.

like image 58
Pol Avatar answered May 08 '26 23:05

Pol