# 描述符覆盖行为
# 描述器分类
descr.__get__(self, obj, type=None) -> value
descr.__set__(self, obj, value) -> None
descr.__delete__(self, obj) -> None
同时定义__get__() 和 __set__()的称为数据描述器或强制描述符。
仅定义 __get__()的称为非数据描述器或遮盖型描述符。
仅定义 __set__()的称为覆盖型描述符,没有定义__set__的称为非覆盖描述符。
# 覆盖型描述符和非覆盖型描述符
# 覆盖性描述符
覆盖性描述符:实现了__set__方法的描述符
没有实现
__get__方法的话如果实例属性空间
__dict__中有同名属性,则获取时会被实例属性空间中的同名属性覆盖,但是赋值时还是被__set__接管print(man.over_no_get) # <__main__.OverridingNoGet object at 0x000002009326F6C8> man.over_no_get = "MMMMM" # -> OverridingNoGet.__set__(<OverridingNoGet object>, <Managed object>, <str object>) man.__dict__["over_no_get"] = "man-over_no_get" print(man.over_no_get) # man-over_no_get man.over_no_get = "MMMMM" # -> OverridingNoGet.__set__(<OverridingNoGet object>, <Managed object>, <str object>) print(man.over_no_get) # man-over_no_get
实现了
__get__方法- 明显,获取和赋值都会被接管
# 非覆盖描述符
非覆盖描述符:没有实现__set__方法的描述符
因为没有实现__set__所以只要产生赋值操作都会在实例属性空间中创建同名属性,之后再获取或者赋值都走属性空间
print(man.non_over) # -> NonOverriding.__get__(<NonOverriding object>, <Managed object>, <class Managed>)
# None
man.non_over = "NNNNN"
print(vars(man)) # {'non_over': 'NNNNN'}
print(man.non_over) # NNNNN
man.__dict__["non_over"] = "man-non_over"
print(man.non_over) # man-non_over
man.non_over = "NNNNN"
print(man.non_over) # NNNNN
# 总结
总的来说,python按照以下顺序查找属性
- MRO顺序中的类的类属性中的数据描述符
- 实例属性空间中的同名属性
- MRO顺序中的类的类属性中的非数据描述符
- MRO顺序中的类的类属性中的普通属性