在我的模块中,我有几个函数依赖于启动时间较长的外部模块。如何使用
LazyLoader
?如果我有
import veggies
或
import veggies.brussels.sprouts
或
from veggies.brussels import sprouts
我如何替换这些语句以使用
LazyLoader
,以便模块内容的执行被推迟到需要时?
从文档中并不能立即明显看出如何使用它。没有示例,无效代码搜索仅出现Python本身包含的单元测试。
原始问题有一些代码似乎是延迟完全导入的:
以下文件延迟导入两个模块:
import sys
import importlib.util
def lazy(fullname):
try:
return sys.modules[fullname]
except KeyError:
spec = importlib.util.find_spec(fullname)
module = importlib.util.module_from_spec(spec)
loader = importlib.util.LazyLoader(spec.loader)
# Make module with proper locking and get it inserted into sys.modules.
loader.exec_module(module)
return module
os = lazy("os")
myown = lazy("myown")
print(os.name)
myown.test()
为了测试,我在
myown.py
中使用了以下内容。
print("Executed myown.")
def test():
print("OK")
效果很好(Python 3.8a0)。
在此线程之后 6 年,我正在测试一些延迟导入的方法,以便可以缩短应用程序的启动时间,而 PEP690 不可用(Python 3.12)
在测试 LazyLoader 方法时,请注意 Python 不会保留该导入,并且您的惰性对象只会像任何其他对象一样被垃圾收集。
这是一个例子
lib.py
print('Executing lib.py')
class MyClass():
def get_name(self):
return self.__class__.__name__
主.py
def lazy(fullname):
import sys
import importlib.util
try:
return sys.modules[fullname]
except KeyError:
spec = importlib.util.find_spec(fullname)
module = importlib.util.module_from_spec(spec)
loader = importlib.util.LazyLoader(spec.loader)
# Make module with proper locking and get it inserted into sys.modules.
loader.exec_module(module)
return module
def method1():
lib = lazy("lib")
my_class = lib.MyClass()
print(my_class.get_name())
def method2():
import lib
my_class = lib.MyClass()
print(my_class.get_name())
if __name__ == '__main__':
methods = [method1, method2]
for method in methods:
print('Executing {}'.format(method.__name__))
for _ in range(2):
method()
print('---------------------------------')
结果:
Executing method1
Executing lib.py
MyClass
Executing lib.py
MyClass
---------------------------------
Executing method2
Executing lib.py
MyClass
MyClass
---------------------------------