python – __getattribute__什么时候不参与属性查找?

考虑以下:

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__约束的属性列表是什么?

最佳答案

The implementation of __getattribute__ obviously fails all lookups

让我们说它失败了所有的香草查找.

那么__getattribute__本身是如何首先被调用的,因为它也是类的一个属性?

属性将引用点后面的任何名称.因此,要获取类实例的属性,当您尝试访问该属性(通过点引用)时,将无条件地召唤__getattribute__.

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

Why is it still possible to instantiate an object?

当你这样做时:

a = A()

__init__方法在幕后调用,但不是通过vanilla查找.语言处理这个.同样适用于其他方法,如__setattr __,__ delattr __,__ getattribute__以及其他方法.

但如果你直接调用__init__:

a.__init__()

这会引起错误.呃,这没有任何意义,因为课程已经初始化了.

更巧妙的是,如果您尝试通过点引用从类实例访问__getattribute__:

a.__getattribute__

它也会引发一个AttributeError;尝试在属性__getattribute__上查找同一方法的语言调用,但失败并出现错误.

What’s the list of attributes that are not subject to
__getattribute__?

总之,当您尝试通过点引用访问任何属性时,__ getattribute__会播放.只要您不尝试显式调用魔术方法,就不会调用__getattribute__.

点赞