以下代码说明了我要改进的初始情况:
# 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()
表示路径。其中一些路径操作函数可能使用相同的全局变量,该全局变量仅应使用一次。为了使模式更可重用和可插入,我希望延迟加载透明地进行。
您可以使用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