Python 懒加载属性装饰器(LazyProperty)详解
·
前言
今天学习一个开源项目的时候,发现其中一个很有意思的用法,叫做懒加载属性装饰器,他有什么用呢?
在你平时开发的时候,你可能会遇到这样的情况:某个对象的属性计算起来比较复杂,但又不能直接写死,避免后续不好修改,这个时候如果能做到“第一次用的时候才计算,后续访问直接使用缓存结果”,就能提高效率
这就是 懒加载属性(Lazy Property) 的作用。本文将带你一步步理解并实现一个 LazyProperty 装饰器。
什么是懒加载属性
懒加载属性是一种延迟计算 / 初始化的思想
好处:
-
节省不必要的计算开销
-
提高对象实例化速度
-
属性访问更高效(第一次之后几乎是 O(1))
为什么不用 @property
这里虽然将计算方法修饰为属性,但你每次调用的时候,实质上还是会重新计算
如果属性计算复杂或耗时,这样的重复计算就非常低效。
LazyProperty 的实现
class LazyProperty(object):
"""
懒加载属性装饰器
实现属性的延迟计算和结果缓存,避免重复计算。
第一次访问属性时执行计算,后续访问直接返回缓存结果。
"""
def __init__(self, func):
"""初始化懒加载装饰器
Args:
func: 被装饰的函数,用于计算属性值
"""
self.func = func
def __get__(self, instance, owner):
"""属性访问拦截器
当通过实例访问被装饰的属性时,此方法会被调用。
Args:
instance: 访问属性的实例对象
owner: 实例所属的类
Returns:
如果通过类访问,返回装饰器本身;
如果通过实例访问,返回计算后的属性值(并缓存结果)。
"""
if instance is None:
# 通过类访问时(如 Config.serverHost),直接返回装饰器本身
return self
else:
# 通过实例访问时,执行原始函数计算属性值
value = self.func(instance)
# 将计算结果缓存到实例上,覆盖掉原方法
setattr(instance, self.func.__name__, value)
# 返回计算结果
return value
对于每一个获取函数而言,都加了一个懒加载的装饰器:
class Config:
@LazyProperty
def server_host(self):
print("计算 serverPort...")
return "127.0.0.1"
config = Config()
print(config.server_host) # 第一次访问,会打印并返回结果
print(config.server_host) # 第二次访问,直接返回缓存

第一次计算的时候,会将该函数传入到LazyProperty,然后进行计算,通过setattr将ConfigHandler的server_host的值改为计算结果,也就是说给这个对象的计算方法直接改为属性,所以下一次计算的时候就不会再调用函数,而且调用一个对象的属性。
更多推荐

所有评论(0)