有时,我们需要在一个函数执行之前加载一些什么,而且只在第一次执行前加载一次。
标题中说这是“懒加载”是因为,如果条件允许,你完全可以手动在程序最开头执行一遍加载,而不用等用到了函数再加载。
常用的解决方法是建个全局变量判断:
loaded = False
def load():
x = 'bruh'
print('exec load')
globals().update(locals()) #同步局部变量到全局
def main():
global loaded
if not loaded:
load()
loaded = True
print('exec main')
print('value of x:',x)
main()
main()
main()
执行结果:
exec load
exec main
value of x: bruh
exec main
value of x: bruh
exec main
value of x: bruh
但是有点麻烦,而且这种情况一多起来,总感觉自己一直在复制粘贴。
下面来看看如何用装饰器抽象这一功能。
loadonce.py
state_dict = {}
def loadonce(loader_func):
def load_decorator(target_func):
def decorated(*args, **kwargs):
loaded = state_dict.get(id(target_func), False)
if not loaded:
loader_func()
state_dict[id(target_func)] = True
return target_func(*args, **kwargs)
return decorated
return load_decorator
test.py
from loadonce import loadonce
def load():
x = 'bruh'
print('exec load')
globals().update(locals()) #同步局部变量到全局
@loadonce(load)
def main():
print('exec main')
print('value of x:',x)
main()
main()
main()
test.py
执行结果:
exec load
exec main
value of x: bruh
exec main
value of x: bruh
exec main
value of x: bruh