class cached_property(object):
"""
Decorator that converts a method with a single self argument into a
property cached on the instance.
Optional ``name`` argument allows you to make cached properties of other
methods. (e.g. url = cached_property(get_absolute_url, name='url') )
"""
def __init__(self, func, name=None):
self.func = func
self.__doc__ = getattr(func, '__doc__')
self.name = name or func.__name__
def __get__(self, instance, cls=None):
if instance is None:
return self
res = instance.__dict__[self.name] = self.func(instance)
return res
装饰器类解释:
- cache_propery为一个装饰器类,装饰某个函数
- 定义了一个name参数,可以自己传或者直接读取被装饰的函数名
- __get__方法表名这个装饰器是个描述符装饰器并且为非数据描述符
- 这个get方法执行了被装饰的函数并将返回的数据保存到了实例的__dict__里面
- 属性的读取优先级你应该要了解:数据描述符 > __dict__读取 > 非数据描述符
class RawDb(object):
@cached_property
def columns(self):
return 1
rd = RawDb()
print(rd.__dict__)
print(rd.columns)
print(rd.__dict__)
print(rd.columns)
上面的打印输出:
{}
1
{‘columns’: 1}
1
解释如下:
- 实例rd第一次运行rd.columns,会调用__get__方法并将返回的数据保存在实例rd的__dict__里面’
- 访问rd.columns的时候,为什么会直接去调用描述符的 get 方法?因为当访问的属性为描述符时,会将 rd.columns 转化为RawDb.dict[‘columns’].get(rd, RawDb) 来访问。
- 实例rd第二次运行rd.columns,为什么不在运行__get__方法?这是因为__dict__的读取优先于非数据描述符,上面第一次运行我们已经把返回数据保存到了__dict__中,所以直接从__dict__中读取了。
————————————————
版权声明:本文为CSDN博主「zhexiao27」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/andybegin/article/details/80797256