Bha*_*rel 4 python python-descriptors
我读的地方有关的事实,你可以有一个描述符有__set__和无__get__.
它是如何工作的?
它算作数据描述符吗?它是非数据描述符吗?
这是一个代码示例:
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
Run Code Online (Sandbox Code Playgroud)
您在示例中给出的描述符是数据描述符.
在设置属性时,与任何其他数据描述符一样,它具有最高优先级并且被调用如下:
type(myinst).__dict__["attr"].__set__(myinst, 1234)
Run Code Online (Sandbox Code Playgroud)
反过来,attr根据您的__set__方法添加到实例字典.
在属性访问时,检查描述符是否有__get__方法但是失败,导致搜索被重定向到实例的字典,如下所示:
myinst.__dict__["attr"]
Run Code Online (Sandbox Code Playgroud)
如果在实例字典中找不到它,则返回描述符本身.
这种行为很快就会记录在数据模型中,如下所示:
如果它没有定义
__get__(),那么访问该属性将返回描述符对象本身,除非对象的实例字典中有值.
常见用例包括避免{instance: value}描述符中的字典,以及以有效的方式缓存值.
在Python 3.6中,__set_name__添加到描述符协议中,因此无需在描述符内指定名称.这样,您的描述符可以这样写:
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()
Run Code Online (Sandbox Code Playgroud)