1

我正在尝试覆盖 getattr 方法,根据我的理解,以下代码片段中应该有无限循环,因为默认情况下 object.__getattribute__(self,attr)被调用,它将调用覆盖的 getattr 方法,因为属性“不存在”不存在命名空间,这个过程将不断重复。谁能帮我弄清楚为什么这里没有观察到这种行为。

此外,我无法弄清楚为什么在使用点符号访问属性时完成对 getattribute 的隐式调用时没有引发 AttributeError,而当我们试图在方法中显式调用 getattribute 时第二次引发它

class Test(object):

    #Act as a fallback and is invoked when getattribute is unable to find attribute

    def __getattr__(self,attr):

        print "getattr is called"
        return object.__getattribute__(self,attr) #AttributeError is raised

t=Test([1,2,3,4])

b = t.notpresent
4

2 回答 2

4

object.__getattribute__Test.__getattr__.

这里不涉及循环。

此外,根据文档__getattribute__不会隐式调用__getattr__.

修改后更新

__getattribute__调用的 C 实现。尤其是那slot_tp_getattr_hook部分。

在您的情况下,属性查找失败导致执行调用您的自定义__getattr__函数的第 6072 行。

从那时起,它AttributeError已经被清除了。但是您的呼叫object.__getattribute__会将其设置回去,并且第 6074 或 6075 行将无法处理它。

object.__getattribute__调用是这样实现,因此(重新)引发AttributeError(第 1107 行)。

于 2015-07-21T08:36:37.287 回答
0

因为__getattribute__通常只在__dict__对象和类似位置查找属性 - 它不会隐式调用__getattr__来检索属性。

请注意,如果未能找到该属性,如果__getattribute__会调用__getattr____getattr__方法可能会被调用两次(因为查找应该在失败时调用)。__getattribute____getattr____getattribute__

于 2015-07-21T08:39:48.163 回答