我读了一下python的对象属性查找(这里:https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/#object-attribute-lookup).
看起来很直接,所以我试了一下(python3):
class A:
def __getattr__(self, attr):
return (1,2,3)
a = A()
a.foobar #returns (1,2,3) as expected
a.__getattribute__('foobar') # raises AttributeError
Run Code Online (Sandbox Code Playgroud)
我的问题是不是两个应该是相同的?
为什么第二个会引发属性错误?
所以答案显然是a.foobarIS的逻辑不同于逻辑a.__getattribute("foobar").根据数据模型:a.foobar调用a.__getattribute("foobar"),如果它引发AttributeError,则调用a.-__getattr__('foobar')
所以看来这篇文章在他们的图表中有一个错误.它是否正确?
还有一个问题:a.foobar的真正逻辑在哪里?我认为它在__getattribute__但显然不完全.
编辑: 不重复
__getattr__与__getattribute__之间的区别.我问这里有什么之间的不同object.foo和object.__getattribute__("foo").这__getattr__与vs 不同,__getatribute__这是微不足道的......
获得__getattribute__比实际更重要的印象很容易.thing.attr不直接翻译thing.__getattribute__('attr'),__getattribute__也不负责打电话__getattr__.
回退__getattr__发生在外部属性访问机制的部分__getattribute__.属性查找过程的工作方式如下:
__getattribute__通过直接搜索对象的类型的MRO来找到该方法,绕过常规属性查找过程.__getattribute__.
__getattribute__返回了某些内容,则属性查找过程完成,这就是属性值.__getattribute__引发非AttributeError,则属性查找过程完成,异常传播出查找.__getattribute__引发一个AttributeError.查找继续.__getattr__与我们发现的方法相同的方法__getattribute__.
__getattr__,则属性查找过程完成,并__getattribute__传播AttributeError .__getattr__,并返回或提高任何__getattr__回报或加注.至少,就语言语义而言,它就是这样的.就低级实现而言,这些步骤中的一些可以在不需要的情况下进行优化,并且存在类似于tp_getattro我未描述的C钩子.除非你想深入了解CPython解释器源代码,否则你不必担心这种事情.
| 归档时间: |
|
| 查看次数: |
526 次 |
| 最近记录: |