python 动态加载 延迟导入

众所周知import是用来加载Python模块的,其实import是调用内建函数__import__来工作的,这就使我们动态加载模块变成了可能。

1. import glob, os  
2.   
3. modules = []  
4.   
5. for module_file in glob.glob('*-plugin.py'):        #glob.glob得到当前目录下匹配字符串的文件名  
6.       
7. #将文件名以点号分开  
8. print(os.path.basename(module_file))  
9. print(ext)  
10. #获得模块  
11. 'hello')      #根据函数名获得函数  
12. print(fun)  
13.         fun()  
14.         modules.append(module)  
15.   
16. for module in modules:  
17.     module.hello()

下面我们来实现一个动态加载的类,当第一次使用该模块时,才会被加载

1. class LazyImport:  
2. def __init__(self, module_name):  
3. self.module_name = module_name  
4. self.module = None  
5.   
6. def __getattr__(self, funcname):  
7. if self.module is None:  
8. self.module = __import__(self.module_name)  
9. print(self.module)  
10. return getattr(self.module, funcname)  
11.   
12.   
13.   
14. string = LazyImport('string')  
15. print(string.ascii_lowercase)

其中,这个类的__getattr__方法,只有当这个类的对象调用了某个方法,并且找不到这个方法的时候会被自动调用。

一般象a.b这样的形式,python可能会先查找a.__dict__中是否存在,如果不存在会在类的__dict__中去查找,再没找到可能会去按这种方法去父类中进行查找。实在是找不到,会调用__getattr__,如果不存在则返回一个异常。那么__getattr__只有当找不到某个属性的时候才会被调用。众所周知import是用来加载Python模块的,其实import是调用内建函数__import__来工作的,这就使我们动态加载模块变成了可能。


1. import glob, os  
2.   
3. modules = []  
4.   
5. for module_file in glob.glob('*-plugin.py'):        #glob.glob得到当前目录下匹配字符串的文件名  
6.       
7. #将文件名以点号分开  
8. print(os.path.basename(module_file))  
9. print(ext)  
10. #获得模块  
11. 'hello')      #根据函数名获得函数  
12. print(fun)  
13.         fun()  
14.         modules.append(module)  
15.   
16. for module in modules:  
17.     module.hello()