Python 什么时候不参与属性查找?

Python 什么时候不参与属性查找?,python,attributes,Python,Attributes,考虑以下几点: 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

考虑以下几点:

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
\uuuu getattribute\uuuu
的实现显然会导致所有查找失败。我的问题是:

  • 为什么仍然可以实例化一个对象?我原以为
    \uuuu init\uuu
    方法本身的查找也会失败
  • 不受
    \uuu getattribute\uuu
    约束的属性列表是什么
\uuuu getattribute\uuuu
的实现显然会导致所有查找失败

假设它对所有香草查找都失败

既然
\uuuu getattribute\uuuu
本身也是类的一个属性,那么它首先是如何被调用的呢


属性将引用点后面的任何名称。因此,为了获取类实例的属性,当您尝试访问该属性(通过点引用)时,
\uuu getattribute\uuuu
将被无条件调用

然而,像
\uuuu init\uuuu
这样的神奇方法是语言构造的一部分,因此不能直接调用(通过点引用),因为它们是作为语言的一部分实现的

为什么仍然可以实例化一个对象

当您这样做时:

a = A()
\uuuu init\uuu
方法在后台被调用,但不是通过普通的查找。语言处理这个问题。这同样适用于其他方法,如
\uuuuuu setattr\uuuuuuuu
\uuuu delattr\uuuuuuuu
\uuuuu getattribute\uuuuuuuu

但是如果您直接调用
\uuuuu init\uuuu

a.__init__()
这会引起一个错误。呃,这没有任何意义,因为这个类已经初始化了

更微妙的是,如果您试图通过点引用从类实例访问
\uuuu getattribute\uuuu

a.__getattribute__
它还会引发一个
属性错误
;同一方法的语言调用尝试查找属性
\uuu getattribute\uuu
,但失败,出现错误


不受限制的属性列表是什么
\uuuu获取属性\uuuuu


总之,当您尝试通过点引用访问任何属性时,
\uuuuuu getattribute\uuuuuu
将发挥作用。只要你不尝试显式地调用一个神奇的方法,
\uuuuuGetAttribute\uuuuuu
就不会被调用。

值得注意的是,访问
\uuuuuuu dict\uuuuuu
并不会调用
\uuuuuuuGetAttribute\uuuuuu()
。啊,我现在看到了区别。我认为即使在班级之外也是如此。我刚刚做了一些测试,似乎在类主体之外访问
\uuuuu dict\uuuuuuuu
将调用
\uuuuuuu getattribute\uuuuuuuu
,但不会调用
\uuuuuu getattr\uuuuuuuuuuuu
。我想知道他们为什么要做出区别。@zondo访问
self.\uuuuu dict\uuuuuuuuuuu
也需要
\uuuuuuu getattribute\uuuuuuu
<如果定义了
\uuuu getattr\uuuuu
,而不是
\uuu getattr\uuuu
,当通过
\uuuu getattr\uuuuu
找不到属性时,才调用code>\uu getattr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuu>作为最后手段,那么访问任何属性都将导致调用
\uu getattr\uuuuuuuuuuuu
。然而,访问
\uuuu dict\uuuuu
不会调用它。如果您定义了
\uuuuu getattribute\uuuuuuuuuuuuuuu
,但没有定义
\uuuuuuuuu getattr\uuuuuuuuuuu
,则即使在访问
\uuuuuuuu dict\uuuuuuuuuuuuuuuu
时也会调用它。谢谢,这很有。参考Python文档中明确说明这一点的地方,对未来的读者会有所帮助。