众所周知import是用来加载Python模块的,其实import是调用内建函数__import__来工作的,这就使我们动态加载模块变成了可能。
import glob, os modules = [] for module_file in glob.glob('*-plugin.py'): #glob.glob得到当前目录下匹配字符串的文件名 module_name, ext = os.path.splitext(os.path.basename(module_file)) #将文件名以点号分开 print(os.path.basename(module_file)) print(ext) module = __import__(module_name) #获得模块 fun = getattr(module, 'hello') #根据函数名获得函数 print(fun) fun() modules.append(module) for module in modules: module.hello()
class LazyImport: def __init__(self, module_name): self.module_name = module_name self.module = None def __getattr__(self, funcname): if self.module is None: self.module = __import__(self.module_name) print(self.module) return getattr(self.module, funcname) string = LazyImport('string') print(string.ascii_lowercase)
一般象a.b这样的形式,python可能会先查找a.__dict__中是否存在,如果不存在会在类的__dict__中去查找,再没找到可能会去按这种方法去父类中进行查找。实在是找不到,会调用__getattr__,如果不存在则返回一个异常。那么__getattr__只有当找不到某个属性的时候才会被调用。