6y after this thread, I am testing some approaches to lazy importing so that I can improve the startup time of an app and while PEP690 is not available (Python 3.12)
While testing the LazyLoader approach, be mindful that Python doesn't keep that import and your lazy object just gets garbage collected as any other one.
Here's an example
lib.py
print('Executing lib.py')
class MyClass():
def get_name(self):
return self.__class__.__name__
main.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('---------------------------------')
results:
Executing method1
Executing lib.py
MyClass
Executing lib.py
MyClass
---------------------------------
Executing method2
Executing lib.py
MyClass
MyClass
---------------------------------
LadyLoader
? – Institution