Python中getattribute背后的理性是什么?

时间:2013-09-26 03:38:48

标签: python

我试图在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)

然后我测试了下面的代码:

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>

有人能对输出有明确的解释吗?我看到很多“调用了Metaclass getattribute”,这意味着多次调用__getattribute__()

1 个答案:

答案 0 :(得分:1)

我做了同样的事情。除了打印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)

得到了这个结果:

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>

非常不言自明。第一个参数是对象,第二个参数是属性。