用于延迟初始化的代理对象

问题描述 投票:0回答:2

是否有任何现成的 Python 模块提供了一个易于使用的代理对象,仅在真正需要时初始化“真实”对象?

理想情况下,我正在寻找一种透明的实现,以便处理此代理对象的代码不需要知道它不是实际的对象。

我想这样使用它:

class Example:
    def __init__(self):
        print("Example initialized")

lazy = Proxy(Example)
print(isinstance(lazy, Example))
# Example initialized
# True

如您所见,它的行为非常像单元测试.MagicMock。

如果没有任何库提供这样的功能,我将自己实现它,但我想确保没有其他人这样做过。

编辑

我希望这个代理对象遵循一个完整的实现像这样

python lazy-initialization proxy-classes
2个回答
3
投票

我发现模块 lazy-object-proxy 正是这样做的。

值得一提的是,正如 @Marat 指出的那样 Django 也提供了一个解决方案,尽管我不想为此导入 Django,但如果您已经在项目中使用它,那将是一个完美的解决方案。


0
投票

有 Werkzeug 的 LocalProxy:

# external_module.py
from werkzeug.local import LocalProxy

_internal = None

def init_value():
    global _internal
    _internal = "I'm ready now!"

proxy = LocalProxy(lambda: _internal)
# main.py
from external_module import _internal, proxy, init_value

print(_internal)   # None
print(proxy)       # None
init_value()
print(proxy)       # I'm ready now!
print(_internal)   # None

文档中未涵盖延迟加载方面,但

LocalProxy
可以满足您的要求,即:

  1. 充当另一个对象的代理
  2. 推迟评估直到访问对象(例如,与导入时相反)
  3. 将自身呈现为代理对象(来自文档):

__repr__
__class__
被代理,因此
repr(x)
isinstance(x, cls)
看起来像被代理的对象。使用
issubclass(type(x), LocalProxy)
来检查对象是否是代理。”

from werkzeug.local import LocalProxy

class Example:
    def __init__(self):
        print("Example initialized")

lazy = LocalProxy(Example)              # Example initialized
print(isinstance(lazy, Example))        # True
© www.soinside.com 2019 - 2024. All rights reserved.