为什么在hassattr内部调用Python中描述符的__get__方法?

问题描述

假设

class D:
    def __init__(self,id): self.id = id

    def __get__(self,obj,type=None):
        print(self.id,"__get__ is called")

class C:
    d1 = D(1)
    d2 = D(2) 
    d3 = D(3)

c = C()

然后在调用hasattr(c,"d1")期间调用__get__的{​​{1}}方法。为什么? C.d1不应该只检查字典吗?

在交互式cpython-version-3.6.10会话中按下hasattr()以完成操作时,会发生相同(但很奇怪)的情况,与<tab>中一样。在这种情况下,将为除最后一个属性之外的所有匹配属性调用c.d<tab>。 这是怎么回事?

解决方法

如果您在help(或documentation)中查看hasattr

Help on built-in function hasattr in module builtins:

hasattr(obj,name,/)
    Return whether the object has an attribute with the given name.

    This is done by calling getattr(obj,name) and catching AttributeError.

所以不,它不仅会“检查字典”,而且不能这样做,因为并非所有对象都将字典作为名称空间开头,例如内置对象或带有__slots__的用户定义对象。

getattr(obj,name)将正确调用等效的机器,如下:

obj.name

哪个会调用描述符的__get__

,

不确定制表符是否完成,但是hasattr会调用__get__。是documented as well

参数是一个对象和一个字符串。如果结果为True, string是对象属性之一的名称,如果不是False。 (这是通过调用getattr(object,name)并看到 是否引发AttributeError。)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...