查公司信息的网站,游戏网站设计论文,汕头做网站设计,规划设计公司年终总结描述符
描述符允许自定义在引用一个对象的属性时应该完成的事情。它是一个类#xff0c;定义了另一个类的属性的访问方式。换句话说#xff0c;一个类可以将属性管理委托给另一个类。
描述符类基于3个特殊方法#xff0c;这3个方法组成了描述符协议#xff08;descriptor…描述符
描述符允许自定义在引用一个对象的属性时应该完成的事情。它是一个类定义了另一个类的属性的访问方式。换句话说一个类可以将属性管理委托给另一个类。
描述符类基于3个特殊方法这3个方法组成了描述符协议descriptor protocol
__set__(self, obj, typeNone)在设置属性时将调用这一方法。在下面的示例中我们将其称为setter。__get__(self, obj, value)在读取属性时将调用这一方法被称为getter。__delete__(self, obj)对属性调用del时将调用这一方法。
实现了__get__()和__set__()的描述符被称为数据描述符data descriptor。
如果只实现了__get__()那么就被称为非数据描述符non-data descriptor。
代码实例
class RevealAccess(object):一个数据描述符正常设定值并返回值同时打印出记录访问的信息。def __init__(self, initvalNone, namevar):self.val initvalself.name namedef __get__(self, obj, objtype):print(Retrieving, self.name)return self.valdef __set__(self, obj, val):print(Updating, self.name)self.val valclass MyClass(object):x RevealAccess(10, var x)m MyClass()
m.x
m.x 20运行结果为
Retrieving var x
Updating var x通过这个例子我们可以看出当RevealAccess类对象被调用时触发__get__当对RevealAccess类对象赋值时触发__set__。
延迟求值属性
描述符可以将类属性的初始化延迟到被实例访问时。在属性的初始化依赖全局应用上下文或者初始化的代价很大但在导入类的时候不能确保一定会用到这个属性的时候非常有用。
class InitOnAccess:def __init__(self, klass, *args, **kwargs):self.klass klassself.args argsself.kwargs kwargsself._initialized Nonedef __get__(self, instance, owner):if self._initialized is None:print(initialized!)self._initialized self.klass(*self.args, **self.kwargs)else:print(cached!)return self._initializedclass MyClass:lazily_initialized InitOnAccess(list, argument)m MyClass()
print(m.lazily_initialized)
print(m.lazily_initialized)运行结果如下
initialized!
[a, r, g, u, m, e, n, t]
cached!
[a, r, g, u, m, e, n, t]可以看到只有在访问到InitOnAccess实例化对象时才会初始化并且只会被初始化一次。