请考虑以下事项:
class A(object):
def __init__(self):
print 'Hello!'
def foo(self):
print 'Foo!'
def __getattribute__(self, att):
raise AttributeError()
a = A() # Works, prints "Hello!"
a.foo() # throws AttributeError as expected
__getattribute__
的实现显然无法完成所有查找。我的问题:
__init__
方法本身也会失败。__getattribute__
?答案 0 :(得分:2)
__getattribute__
的实现显然无法完成所有查找
让我们说它无法进行所有的香草查找。
那么__getattribute__
本身是如何首先被调用的,因为它也是类的一个属性?
属性将引用点后面的任何名称。因此,要获取类实例的属性,当您尝试访问该属性时(通过点引用),将无条件地召唤__getattribute__
。
然而像__init__
这样的魔术方法是语言构造的一部分,因此不会直接调用(通过点引用),因为它们是作为语言的一部分实现的。
为什么仍然可以实例化一个对象?
当你这样做时:
a = A()
__init__
方法在幕后调用,但不是通过vanilla 查找。语言处理这个。同样适用于__setattr__
,__delattr__
,__getattribute__
等其他方法。
但如果您直接致电__init__
:
a.__init__()
会引发错误。呃,这没有任何意义,因为课程已经初始化了。
更巧妙的是,如果您尝试通过点引用从类实例访问__getattribute__
:
a.__getattribute__
它也会引发AttributeError
;尝试在属性__getattribute__
上查找同一方法的语言调用,但失败并显示错误。
不受限制的属性列表是什么
__getattribute__
?
总之,当您尝试通过点引用访问任何属性时,__getattribute__
会播放。只要您不尝试显式调用魔术方法,就不会调用__getattribute__
。