为什么在 python 中覆盖 getattr 方法时没有无限循环
Why there is no infinite loop while overriding getattr method in python
根据我的理解,我正在尝试覆盖 getattr 方法
默认情况下,以下代码片段中应该存在无限循环
调用 object.__getattribute__(self,attr) 将调用覆盖的 getattr 方法,因为属性 'notpresent' 不存在于命名空间中,并且此过程将继续重复。谁能帮我弄清楚为什么这里没有观察到这种行为。
此外,我无法弄清楚为什么在使用点表示法访问属性时完成对 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
您正在 Test.__getattr__
内呼叫 object.__getattribute__
。
这里不涉及循环。
此外,根据 the docs,__getattribute__
不会隐式调用 __getattr__
。
编辑后更新
Here 是 __getattribute__
调用的 C 实现。特别是 slot_tp_getattr_hook
部分。
在您的情况下,属性查找失败导致第 6072 行调用您的自定义 __getattr__
函数。
从那时起,AttributeError
已被清除。但是您对 object.__getattribute__
的调用会将其设置回去,而第 6074 行或 6075 行将不会处理它。
object.__getattribute__
调用已实现 like so,因此(重新)引发 AttributeError
(第 1107 行)。
因为 __getattribute__
通常只在对象的 __dict__
和类似地方查找属性 - 它不会隐式调用 __getattr__
来检索属性。
请注意,如果 __getattribute__
将调用 __getattr__
,如果 __getattribute__
未能找到该属性,则 __getattr__
方法可能会被调用两次(因为查找应该调用 __getattr__
当 __getattribute__
失败时)。
根据我的理解,我正在尝试覆盖 getattr 方法 默认情况下,以下代码片段中应该存在无限循环 调用 object.__getattribute__(self,attr) 将调用覆盖的 getattr 方法,因为属性 'notpresent' 不存在于命名空间中,并且此过程将继续重复。谁能帮我弄清楚为什么这里没有观察到这种行为。
此外,我无法弄清楚为什么在使用点表示法访问属性时完成对 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
您正在 Test.__getattr__
内呼叫 object.__getattribute__
。
这里不涉及循环。
此外,根据 the docs,__getattribute__
不会隐式调用 __getattr__
。
编辑后更新
Here 是 __getattribute__
调用的 C 实现。特别是 slot_tp_getattr_hook
部分。
在您的情况下,属性查找失败导致第 6072 行调用您的自定义 __getattr__
函数。
从那时起,AttributeError
已被清除。但是您对 object.__getattribute__
的调用会将其设置回去,而第 6074 行或 6075 行将不会处理它。
object.__getattribute__
调用已实现 like so,因此(重新)引发 AttributeError
(第 1107 行)。
因为 __getattribute__
通常只在对象的 __dict__
和类似地方查找属性 - 它不会隐式调用 __getattr__
来检索属性。
请注意,如果 __getattribute__
将调用 __getattr__
,如果 __getattribute__
未能找到该属性,则 __getattr__
方法可能会被调用两次(因为查找应该调用 __getattr__
当 __getattribute__
失败时)。