在"调用描述符" Descriptor HowTo Guide,它说:
" 数据描述符总是覆盖实例字典。
非数据描述符可能会被实例字典覆盖。 "
它还说:
" 该实现通过优先级链工作,使数据描述符优先于实例变量,实例变量优先于非数据描述符,并将最低优先级分配给__getattr __()(如果提供)。 "
然后,非数据描述符应该总是被实例字典覆盖。为何使用" 可能"这里?我该如何理解这一陈述?
答案 0 :(得分:0)
考虑以下配置:
class data_descriptor:
def __get__(self, obj, cls):
return 'data descriptor'
def __set__(self, obj, val):
pass
class non_data_descriptor:
def __get__(self, obj, cls):
return 'non data descriptor'
class X:
attr_data = data_descriptor()
attr_non_data = non_data_descriptor()
无论您是否在实例字典中有项目,数据描述符优先于。但是,非数据描述符可以被实例字典中的项阴影。文档只写'#34;可能被覆盖"因为它取决于实例字典中是否存在碰撞键。
这是一个演示:
>>> x = X()
>>> x.attr_data
'data descriptor'
>>> x.attr_non_data
'non data descriptor'
>>> # populate the instance dict with stuff
>>> x.__dict__.update({'attr_data': 'spam', 'attr_non_data': 'eggs'})
>>> x.attr_data # descriptor wins
'data descriptor'
>>> x.attr_non_data # instance __dict__ wins
'eggs'
>>> del x.attr_non_data # restore descriptor by removing name from __dict__
>>> x.attr_non_data
'non data descriptor'
有关为什么以这种方式设计描述符协议的讨论,请参阅here。