Python 中非数据描述符和实例条目之间的优先级



在Python 3.6文档的"描述符操作指南"的"描述符协议"段落中写道

如果实例的字典具有与 非数据描述符,字典条目优先

也许我理解了一些错误,但是为什么非数据描述符在此示例中优先于实例条目

class Descriptor:
    def __get__( self, instance, owner ):
        print( "__get__ is called" )
        return self.__dict__[self.name]

    def __set_name__( self, owner, name ):
        print( "__set_name__ is called" )
        self.name = name
        self.__dict__[name] = "Hello World"
d = Descriptor()
class MyClass:
    data = d
instance_of = MyClass()
instance_of.d = "Goodbye"
print()
print( instance_of.data )

我预计会输出Goodbye。但是有输出Hello World.

这不是"名称"的意思。这里的"name"指的是类__dict__和实例__dict__中的名称,而不是描述符可能具有的任何名称属性。请参阅以下示例,了解何时重写类描述符。

from pprint import pprint
class Descriptor:
    def __get__( self, instance, owner ):
        return "class"
class MyClass:
    data = Descriptor()
obj = MyClass()
# get the data descriptor's value
print(obj.data) # prints "class"
# set an instance attribute with the same name
obj.data = "instance"
print(obj.data) # prints "instance"
# print the variables of both class and instance
# -- both contain the name "data"
pprint(vars(MyClass)) # prints
# mappingproxy({'__dict__': <attribute '__dict__' of 'MyClass' objects>,
#               '__doc__': None,
#               '__module__': '__main__',
#               '__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
#               'data': <__main__.Descriptor object at 0x034BF1B0>})
print(vars(obj)) # prints
# {'data': 'instance'}
# delete the instance attribute and the descriptor becomes visible again
del obj.data
print(obj.data) # prints "class" again

最新更新