[英]__getattr__ method in python
我今天遇到这个代码,看起来很混乱
class ClassOne:
def __init__(self,some_object):
self.not_important_attribute=some_object
class ClassTwo:
def __init__(self,some_object):
self.tmp=ClassOne(some_object)
def __getattr__(self,attr):
return getattr(self.tmp,attr)
a=ClassTwo('not_important_string')
print(getattr(a,'undefined_attribute',3))
当我们在最后一行使用getattr
时,我们在SubClass
触发__getattr__
方法,然后委托给getattr(self.tmp,attr)
函数,如果该属性未定义且没有给出默认值,则会引发异常。 但是最后一行的值3如何仍然经历所有过程,并最终返回到getattr(a,'undefined_attribute',3)
函数? 因为当我们委托getattr(self.tmp,attr)
时我们没有用于默认值的插槽,这怎么可能?
在你的情况下
getattr(self.tmp,attr)
引发AttributeError,如果getattr有第三个参数(默认值),则返回默认值而不是引发AttributeError
一步一步为什么显示3
值:
超类有一个属性
not_important_attribute
,它在调用构造函数时设置
class ClassOne:
def __init__(self,some_object):
self.not_important_attribute=some_object
这里,在
ClassTwo
构造ClassTwo
,您创建一个ClassOne
实例并将其保存到tmp
变量中。 这意味着当你覆盖__getattr__
你将要求ClassOne
的属性值
print(getattr(a,'not_important_attribute',3))
not_important_string # founds the method
print(getattr(a,'any',3))
3 #doesn't found method, returns default
这是直接做的:
b = ClassOne("not_important_string")
print(getattr(b,'not_important_attribute',3))
not_important_string # founds the method
print(getattr(b,'any',3))
3 # doesn't found method, returns default
当调用getattr(a,'undefined_attribute',3)
您调用标准的python getattr函数并将其传递给默认值。 这实际上将您的自定义getattr包装在ClassTwo中。 我们可以看到通过稍微修改getattr 。
def __getattr__(self, attr, *args, **kwargs):
print(args) # -> empty
print(kwargs) # -> empty
return getattr(self.tmp, attr)
实际上,您可以使用print(a.__getattr__('undefined_attribute', 3))
绕过包装并直接从ClassTwo调用getattr 。 此方法会引发异常。
所以基本上getattr(a,'undefined_attribute',3)
是内部从ClassTwo调用自定义getattr的标准python方法。
class ClassTwo:
...
def __getattr__(self,attr):
return getattr(self.tmp,attr)
getattr(a,'undefined_attribute',3)
方法是一个调用__getattribute__
的包装器,如果__getattribute__
失败,它将调用__getattr__
。 它通过处理异常AttributeError
来实现。 在你的情况下, getattr(a,'undefined_attribute',3)
调用ClassTwo.__getattr__
。
看来你认为当它到达return getattr(self.tmp,attr)
,它会抛出错误或返回某种错误并在那一点完成破解和停止。 但是,在python中,程序会将异常传递给调用堆栈。 沿着调用堆栈的上游,如果该异常得到处理,它将正常退出/完成。 在这种情况下, AttributeError
会沿着调用堆栈传递回getattr(a,'undefined_attribute',3)
。 此getattr
具有AttributeError
默认值,因此它返回3
并正常退出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.