Python 一个有集合但没有集合的描述符是如何工作的?

Python 一个有集合但没有集合的描述符是如何工作的?,python,python-descriptors,Python,Python Descriptors,我在某个地方读到这样一个事实:你可以有一个带有\uuuu set\uuuu的描述符,而不带\uu get\uuu 它是如何工作的 它算作数据描述符吗?它是非数据描述符吗 下面是一个代码示例: class Desc: def __init__(self, name): self.name = name def __set__(self, inst, value): inst.__dict__[self.name] = value pr

我在某个地方读到这样一个事实:你可以有一个带有
\uuuu set\uuuu
的描述符,而不带
\uu get\uuu

它是如何工作的

它算作数据描述符吗?它是非数据描述符吗

下面是一个代码示例:

class Desc:
    def __init__(self, name):
        self.name = name
    def __set__(self, inst, value):
        inst.__dict__[self.name] = value
        print("set", self.name)

class Test:
    attr = Desc("attr")

>>>myinst = Test()
>>> myinst.attr = 1234
set attr
>>> myinst.attr
1234
>>> myinst.attr = 5678
set attr
>>> myinst.attr
5678

您在示例中给出的描述符是数据描述符

在设置属性时,与任何其他数据描述符一样,它具有最高优先级,并被称为:

type(myinst).__dict__["attr"].__set__(myinst, 1234)
然后,根据
\uuu set\uu
方法将
attr
添加到实例字典中

属性访问时,会检查描述符是否具有
\uuuu get\uuu
方法,但失败,导致搜索重定向到实例的字典,如下所示:

myinst.__dict__["attr"]
如果在实例字典中找不到,则返回描述符本身

这种行为很快会记录在类似的文档中:

如果它没有定义
\uuuu get\uuuu()
,则访问该属性将 返回描述符对象本身,除非 对象的实例字典

常见的用例包括避免描述符中的
{instance:value}
字典,以及高效地缓存值


在Python3.6中,描述符协议中添加了
\uuuuu set\u name\uuuu
,因此无需在描述符中指定名称。这样,您的描述符可以这样编写:

class Desc:
    def __set_name__(self, owner, name):
        self.name = name
    def __set__(self, inst, value):
        inst.__dict__[self.name] = value
        print("set", self.name)

class Test:
    attr = Desc()

关于数据模型中记录的行为,在Raymond的指南中有更详细的描述。@wim实际上,我最初提出这个问题的原因是因为在那里没有记录。如果没有
\uuuu get\uuuuu
,数据描述符将不起任何作用。我花了一段时间才弄明白它是如何工作的。我想我自己会把它添加到pydocs中。