本文共 1926 字,大约阅读时间需要 6 分钟。
描述符是一种具有“捆绑行为”的对象属性。访问(获取、设置和删除)它的属性时,实际是调用特殊的方法(get(), set(), delete())。也就是说,如果一个对象定义了这三种方法的任何一种,它就是一个描述符。
通常情况下,访问一个对象的搜索链是怎样的?比如 a.x,首先查询 a._dict_['x'],然后是 type(a)._dict_['x'],一直向上查找,直到找到元类为止(不包括元类)。如果这个属性是一个描述符,Python就会“拦截”这个搜索链,取而代之调用描述符方法(get)。
默认行为是从对象的字典中获取、设置或删除属性。但是,如果属性是一个描述符,Python会调用描述符的相关方法。例如,a.x 可能会调用 Foo._get_ 方法,而不是直接从 a._dict_ 中查找。
_get_ 和 _set_ 方法的对象。_get_ 方法的对象。通常情况下,非数据描述符是非数据描述符。属性访问顺序:
__getattr__() 方法。__getattr__() 方法。方法定义:
_get_, _set_, 和 _delete_ 方法。_get_ 方法。None。None。数据描述符会改变属性的基本获取、设置和删除方式。它可以用于以下场景:
class Foo: def __get__(self, instance, owner): print("执行Foo get方法") def __set__(self, instance, value): print("执行Foo set方法") def __delete__(self): print("执行Foo del方法")class Test: x = Foo() def __init__(self, num): self.x = num# 由于 `x` 是数据描述符,赋值会调用 `Foo.__set__` 方法abc = Test(100)print(abc.x) 输出结果:
abc.__dict__ 中没有 x)class Test: def __init__(self, key, type_data): self.key = key self.type_data = type_data def __set__(self, instance, value): if isinstance(value, self.type_data): instance.__dict__[self.key] = value else: print("赋值类型错误")class People: name = Test('name', str) def __init__(self, name, old): self.name = name self.old = old# 赋值为 str 类型name = 'anec'# 赋值为 int 类型name2 = 123abc = People(name, 23)abc2 = People(name2, 24)print(abc.__dict__)print(abc2.__dict__) 运行结果:
abc.__dict__ 中没有 name,因为 name 是数据描述符abc2.__dict__ 中包含 name,因为 name2 是整数类型,触发了错误提示转载地址:http://ysafk.baihongyu.com/