class B(object):
"""new style class"""
def __getattribute__(self, name):
print '__getattribute__ called'
return super(B, self).__getattribute__(name)
def __getattr__(self, name):
print '__getattr__ called'
def __setattr__(self, name, value):
print '__setattr__ called'
if name in ['forbid', 'refuse']:
raise AttributeError('Attribute name invalid!')
else:
return super(B, self).__setattr__(name, value)
B类定义如上,接下来我尝试对__getattr__,__getattribute__
进行一些测试:
b = B()
setattr(b, 'test', 100)
print b.__dict__
print b.__getattribute__('__dict__')
print b.__getattr__('__dict__')
print getattr(b, '__dict__')
最后结果是:
__getattribute__ called
{'test': 100}
__getattribute__ called
__getattribute__ called
{'test': 100}
__getattribute__ called
__getattr__ called
None
__getattribute__ called
{'test': 100}
这是我的问题:
1. print b.__getattribute__('__dict__')
两次调用__getattribute__
,为什么?
2. print b.__getattr__('__dict__')
首先调用__getattribute__
,然后调用__getattr__
?为什么还没有?
上面的结果对我来说似乎很奇怪。我真的不明白这些方法是如何运作的。任何建议或建议都值得赞赏。谢谢!
答案 0 :(得分:3)
执行__getattribute__
时,第一次b.__getattribute__
来电已完成。你想获得名为__getattribute__
的属性(是的,我知道这听起来很漂亮)。当您请求名为__getattribute__
的属性时,会调用__getattribute__
并在结果中获得__getattribute__
方法。然后,您只需拨打__getattribute__
方法 - 这是__getattribute__
b.__getattr__
调用__getattribute__
来获取名为__getattr__
的属性(是的,我知道)。您获得__getattr__
方法作为回报。然后调用__getattr__
方法。它不会明确地返回任何内容,这意味着它会隐式返回None。
这是您看到some_obj_of_class_B.some_method()
时发生的简化版本:
__getattribute__
来获取名为some_method
的属性。 __getattribute__
打印'我被叫了!'并将其工作委托给object.__getattribute__
(我认为,检查some_obj_of_class_B' s __dict__
,检查其类__dict__
,基类__dict__
,处理描述符等。希望object.__getattribute__
返回some_method
(希望是一个函数,或者更确切地说是一个绑定方法)__getattribute__
。这就是它调用两次的原因。