如何在Python中创建延迟初始化(代理)包装器?
实现延迟初始化的对象包装器
我们需要创建一个包装器,将初始化成本极高的类A的实例化操作,延迟到第一次访问其任意属性(包括直接访问__dict__)时才执行,以此达到func1传入代理后立即执行、func2访问属性时才触发初始化的效果。
修正原代码问题
首先修正原代码中的两处错误:
- 类
A的__init__方法缺少self参数 func2中应访问实例的foo属性,而非类的foo属性
延迟初始化包装器实现
以下是具体实现代码:
import time class A: def __init__(self): time.sleep(42) self.foo = 1 def func1(obj: A): pass def func2(obj: A): print(obj.foo) def wrapper(cls): class LazyProxy: def __init__(self): self._cls = cls self._instance = None def __getattribute__(self, name): # 跳过代理自身内部属性,避免无限递归 if name in ('_cls', '_instance', '__class__'): return super().__getattribute__(name) # 首次访问非内部属性时,初始化真实实例 if self._instance is None: self._instance = self._cls() # 将属性访问转发给真实实例 return getattr(self._instance, name) return LazyProxy()
代码说明
LazyProxy作为代理类,持有目标类cls和未初始化的实例引用_instance__getattribute__拦截所有属性访问:- 对代理自身的内部属性直接返回,避免递归调用
- 访问其他属性时,先检查是否已初始化真实实例,未初始化则执行实例化
- 最后将属性访问转发给真实实例
- 该实现覆盖常规属性访问(如
proxy.foo)和直接访问__dict__(如proxy.__dict__['foo'])的场景,都会触发初始化
测试验证
运行以下代码验证效果:
proxy = wrapper(A) func1(proxy) # 立即执行,不会触发A的初始化 func2(proxy) # 触发A的初始化,等待42秒后打印1
扩展支持特殊方法
如果目标类A包含特殊方法(如__call__、__len__),可在LazyProxy中添加对应方法,确保触发初始化后再转发调用。例如支持__call__的示例:
def __call__(self, *args, **kwargs): if self._instance is None: self._instance = self._cls() return self._instance(*args, **kwargs)
内容的提问来源于stack exchange,提问作者y.selivonchyk
相关产品推荐
相关产品推荐

