1

认为

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__方法C.d1。为什么?不应该hasattr()只查字典吗?

<tab>在交互式 CPython-version-3.6.10 会话中按下完成时会发生相同(但更奇怪) ,如c.d<tab>. 在这种情况下__get__,将为除最后一个之外的所有匹配属性调用。这里发生了什么?

4

2 回答 2

4

如果您查看helpfor 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__

于 2020-09-17T12:08:59.403 回答
2

不确定选项卡完成,但hasattr确实调用__get__. 它也被记录在案

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

于 2020-09-17T12:11:34.947 回答