3

我尝试在python 参考的示例代码下面运行。

>>> 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 invoked”,这意味着__getattribute__()被调用了很多次。

4

1 回答 1

1

我也这样做了。除了打印参数:

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>

很不言自明。第一个参数是对象,第二个是调用的属性。

于 2013-09-26T04:02:20.347 回答