如何实现这种延迟加载模式?

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

以下代码说明了我要改进的初始情况:

# expensive function execution returning a value
def f(x:int):
    print(f"f({x})")
    return 2*x

# the value is to be stored globally
gvar = f(3)

# this function uses the global variable
def g():
    doing_something_with(gvar)
    return

首先,我不希望立即设置gvar,但在首次使用它时(延迟加载):

gvar = None

def g():
    gvar = f(3)
    doing_something_with(gvar)
    return

但是我也不希望每次使用时都设置gvar

gvar = None

def g():
    if gvar is None:
      gvar = f(3)

    doing_something_with(gvar)
    return

最后我希望这尽可能透明地发生-结果应该类似于以下内容:

gvar = magic(f, 3)

def g():
    doing_something_with(gvar)
    return

因此,我可以仅将gvar当作普通变量使用,而实际上它无形地封装了一种将延迟加载其值的机制。

因此,如果我多次拨打g

g() # prints f(3)
g() # -
g() # -

有可能吗?


为您提供更多背景信息。实际情况是FastApi服务,其中g()表示路径。其中一些路径操作函数可能使用相同的全局变量,该全局变量仅应使用一次。为了使模式更可重用和可插入,我希望延迟加载透明地进行。

python-3.x design-patterns lazy-loading
1个回答
0
投票

您可以使用functools.lru_cache对每个值的第一次调用“缓存”结果:

from functools import lru_cache

import time

@lru_cache(maxsize=100)
def f(x):
    time.sleep(1)    
    return x*x

print(time.time())
for x in range(5):
    print(f(x))

print(time.time())
for x in range(5):
    print(f(x))

print(time.time())

输出:

1583003419.4904697
0
1
4
9
16
1583003424.496077  # takes 5 secons due to the sleep
0
1
4
9
16
1583003424.496102 # takes no time at all, due to caching
© www.soinside.com 2019 - 2024. All rights reserved.