懒加载代理模式(Lazy Initialization Proxy Pattern)
LazyProxy
类实现了懒加载代理模式(Lazy Initialization Proxy Pattern)。懒加载是一种设计模式,旨在延迟对象的创建,直到确实需要它时才进行初始化。这可以节省资源,特别是在对象创建开销较大或者对象未必会被使用的情况下。
类定义与初始化
class LazyProxy:
def __init__(self, init_fn):
self._init_fn = init_fn
self._obj = None
-
class LazyProxy:
定义一个名为LazyProxy
的类。 -
def __init__(self, init_fn):
初始化方法,接受一个参数init_fn
,这是一个用于初始化实际对象的函数。 -
self._init_fn = init_fn
将传入的初始化函数保存为实例变量_init_fn
,以便后续调用。 -
self._obj = None
初始化实际对象_obj
为None
,表示对象尚未被创建。
初始化实际对象的方法
def _initialize_obj(self):
if self._obj is None:
self._obj = self._init_fn()
-
def _initialize_obj(self):
定义一个私有方法_initialize_obj
,用于初始化实际对象。 -
if self._obj is None:
检查实际对象是否已被初始化。如果尚未初始化(即_obj
为None
),则进行初始化。 -
self._obj = self._init_fn()
调用初始化函数init_fn
来创建实际对象,并将其赋值给_obj
。
属性访问的拦截
def __getattr__(self, name):
self._initialize_obj()
return getattr(self._obj, name)
-
def __getattr__(self, name):
重载__getattr__
方法,当访问不存在于LazyProxy
实例中的属性时被调用。 -
self._initialize_obj()
确保实际对象已经被初始化。 -
return getattr(self._obj, name)
将属性访问委托给实际对象_obj
,并返回相应的属性值。
属性赋值的拦截
def __setattr__(self, name, value):
if name in ["_init_fn", "_obj"]:
super().__setattr__(name, value)
else:
self._initialize_obj()
setattr(self._obj, name, value)
-
def __setattr__(self, name, value):
重载__setattr__
方法,拦截属性赋值操作。 -
if name in ["_init_fn", "_obj"]:
如果正在设置的是_init_fn
或_obj
,直接在LazyProxy
实例上设置,避免递归调用。 -
super().__setattr__(name, value)
使用父类的__setattr__
方法设置属性。 -
else:
对于其他属性,首先确保实际对象已经初始化。 -
self._initialize_obj()
初始化实际对象。 -
setattr(self._obj, name, value)
将属性赋值委托给实际对象_obj
。
属性删除的拦截
def __delattr__(self, name):
self._initialize_obj()
delattr(self._obj, name)
-
def __delattr__(self, name):
重载__delattr__
方法,拦截属性删除操作。 -
self._initialize_obj()
确保实际对象已经初始化。 -
delattr(self._obj, name)
将属性删除操作委托给实际对象_obj
。
对象的表示
def __repr__(self):
if self._obj is None:
return f"<{self.__class__.__name__} for {self._init_fn} not yet initialized>"
return repr(self._obj)
def __str__(self):
self._initialize_obj()
return str(self._obj)
-
def __repr__(self):
重载__repr__
方法,用于返回对象的官方字符串表示。-
if self._obj is None:
如果实际对象尚未初始化,返回一个表示尚未初始化的字符串。 -
return repr(self._obj)
如果实际对象已初始化,返回实际对象的repr
表示。
-
-
def __str__(self):
重载__str__
方法,用于返回对象的可读字符串表示。-
self._initialize_obj()
确保实际对象已经初始化。 -
return str(self._obj)
返回实际对象的str
表示。
-
用途总结
LazyProxy
类的主要作用是在需要时才初始化实际对象,从而优化资源的使用。具体用途包括但不限于:
- 资源管理:延迟加载占用大量内存或需要耗时初始化的对象,只有在真正需要时才创建它们。
- 性能优化:减少程序启动时的初始化开销,提升启动速度。
- 依赖管理:在存在循环依赖或复杂依赖关系时,通过懒加载避免一些初始化问题。
使用示例
假设有一个需要大量资源的类 HeavyResource
:
class HeavyResource:
def __init__(self):
print("HeavyResource 初始化中...")
# 假设这里有耗时的初始化过程
使用 LazyProxy
来延迟初始化 HeavyResource
实例:
def create_heavy_resource():
return HeavyResource()
proxy = LazyProxy(create_heavy_resource)
print("Proxy 已创建,但 HeavyResource 尚未初始化。")
# 当首次访问属性或方法时,HeavyResource 会被初始化
# 例如:
proxy.some_method()
输出将会是:
Proxy 已创建,但 HeavyResource 尚未初始化。
HeavyResource 初始化中...
只有在实际需要访问 HeavyResource
的属性或方法时,初始化过程才会被触发。这种方式有效地推迟了资源的使用,优化了程序的整体性能。
LazyProxy类定义
class LazyProxy:
def __init__(self, init_fn):
self._init_fn = init_fn
self._obj = None
def _initialize_obj(self):
if self._obj is None:
self._obj = self._init_fn()
def __getattr__(self, name):
self._initialize_obj()
return getattr(self._obj, name)
def __setattr__(self, name, value):
if name in ["_init_fn", "_obj"]:
super().__setattr__(name, value)
else:
self._initialize_obj()
setattr(self._obj, name, value)
def __delattr__(self, name):
self._initialize_obj()
delattr(self._obj, name)
def __repr__(self):
if self._obj is None:
return f"<{self.__class__.__name__} for {self._init_fn} not yet initialized>"
return repr(self._obj)
def __str__(self):
self._initialize_obj()
return str(self._obj)