懒加载代理模式(Lazy Initialization Proxy Pattern)

LazyProxy 类实现了懒加载代理模式(Lazy Initialization Proxy Pattern)。懒加载是一种设计模式,旨在延迟对象的创建,直到确实需要它时才进行初始化。这可以节省资源,特别是在对象创建开销较大或者对象未必会被使用的情况下。

类定义与初始化

python 复制代码
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

    初始化实际对象 _objNone,表示对象尚未被创建。

初始化实际对象的方法

python 复制代码
    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:

    检查实际对象是否已被初始化。如果尚未初始化(即 _objNone),则进行初始化。

  • self._obj = self._init_fn()

    调用初始化函数 init_fn 来创建实际对象,并将其赋值给 _obj

属性访问的拦截

python 复制代码
    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,并返回相应的属性值。

属性赋值的拦截

python 复制代码
    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

属性删除的拦截

python 复制代码
    def __delattr__(self, name):
        self._initialize_obj()
        delattr(self._obj, name)
  • def __delattr__(self, name):

    重载 __delattr__ 方法,拦截属性删除操作。

  • self._initialize_obj()

    确保实际对象已经初始化。

  • delattr(self._obj, name)

    将属性删除操作委托给实际对象 _obj

对象的表示

python 复制代码
    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 类的主要作用是在需要时才初始化实际对象,从而优化资源的使用。具体用途包括但不限于:

  1. 资源管理:延迟加载占用大量内存或需要耗时初始化的对象,只有在真正需要时才创建它们。
  2. 性能优化:减少程序启动时的初始化开销,提升启动速度。
  3. 依赖管理:在存在循环依赖或复杂依赖关系时,通过懒加载避免一些初始化问题。

使用示例

假设有一个需要大量资源的类 HeavyResource

python 复制代码
class HeavyResource:
    def __init__(self):
        print("HeavyResource 初始化中...")
        # 假设这里有耗时的初始化过程

使用 LazyProxy 来延迟初始化 HeavyResource 实例:

python 复制代码
def create_heavy_resource():
    return HeavyResource()

proxy = LazyProxy(create_heavy_resource)
print("Proxy 已创建,但 HeavyResource 尚未初始化。")

# 当首次访问属性或方法时,HeavyResource 会被初始化
# 例如:
proxy.some_method()

输出将会是:

复制代码
Proxy 已创建,但 HeavyResource 尚未初始化。
HeavyResource 初始化中...

只有在实际需要访问 HeavyResource 的属性或方法时,初始化过程才会被触发。这种方式有效地推迟了资源的使用,优化了程序的整体性能。

LazyProxy类定义

python 复制代码
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)
相关推荐
Auc243 天前
OJ判题系统第4期之判题机模块架构——设计思路、实现步骤、代码实现(工厂模式、代理模式的实践)
java·spring cloud·log4j·mybatis·代理模式·工厂模式
Yang三少喜欢撸铁4 天前
【阿里云免费领取域名以及ssl证书,通过Nginx反向代理web服务】
nginx·阿里云·代理模式·ssl
Blurpath4 天前
什么是静态住宅IP?为什么静态住宅IP能提高注册通过率?
网络·代理模式·ip代理·住宅ip
python算法(魔法师版)5 天前
JavaScript性能优化实战,从理论到落地的全面指南
开发语言·性能优化·前端框架·代理模式
常某某的好奇心8 天前
代理模式(Proxy Pattern)
代理模式
彬彬醤8 天前
全局网络:重构数字时代的连接范式
运维·服务器·网络·数据库·重构·代理模式
菜鸟破茧计划11 天前
穿越数据森林与网络迷宫:树与图上动态规划实战指南
网络·动态规划·代理模式
yy鹈鹕灌顶12 天前
动态规划算法精解(Java实现):从入门到精通
代理模式
帝锦_li13 天前
Java进阶--设计模式
观察者模式·单例模式·代理模式·抽象工厂模式·适配器模式·原型模式
工业甲酰苯胺17 天前
用远程代理模式轻松实现远程服务调用,打开编程新大门
代理模式