class TestInstance: def __init__(self): # 初始化库字典,存放找到的库 self.lib = Proxy() # 使用一个代理对象来模拟层级结构 class Proxy: def __init__(self): self._libObjectDictCache = {} def _getLibInstance(self, libName): """ 返回lib的对象 :param libName: :return: """ # 加载projectlib libNameProject, getProjectLibRes = self._load_lib_folder(r'projectLib\projectA', libName) # 加载commonlib,如果projectlib中没有找到对应的库,这里会作为后备 libNameCommon, getCommonLibRes = self._load_lib_folder(r'commonLib', libName) if getProjectLibRes and getCommonLibRes: classes = (libNameProject, libNameCommon)
# 这里会生成有一个新的类,新类先继承project中的类, 在继承 common lib中的类 cls = type('new_'+libName, tuple(classes), {}) elif getCommonLibRes: cls = libNameCommon elif getProjectLibRes: cls = libNameProject else: raise Exception("can not get lib {}".format(libName)) obj = cls() return obj def _load_lib_folder(self, folder_name, libName): import os import importlib # 获取库文件夹的绝对路径 lib_folder_path = os.path.join(os.path.dirname(__file__), folder_name) print("lib_folder_path",lib_folder_path) def import_module_by_path(module_path, module_name): """ 根据给定的完整路径动态导入模块 """ spec = importlib.util.spec_from_file_location(module_name, module_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module # 遍历库文件夹中的所有文件 getLib = False className = None for filename in os.listdir(lib_folder_path): if filename.endswith('.py') and filename != '__init__.py': # 移除文件扩展名,得到库名 lib_module_name = filename[:-3] print("lib_module_name {} libName {}",lib_module_name ,libName) if lib_module_name == libName: modulePath = os.path.join(folder_name,filename) # 使用绝对导入加载库模块 module = import_module_by_path(modulePath, lib_module_name) # 将库模块添加到lib代理对象的层级结构中 #self.lib 现在是module的集合 ,lib.libA这样的调用返回的来是module,而不是class className = getattr(module, lib_module_name) print("className",className, type(className)) # 把module 里面的class 绑定给self.lib, className()是className的对象,className是一个lib 类class # setattr(self.lib, lib_module_name, className()) # 不绑定给self.lib 而是return className() 出来 getLib = True return className, getLib def __getattr__(self, name): try: print("already") obj = self._libObjectDictCache[name] except KeyError: obj = self._getLibInstance(name) self._libObjectDictCache[name] = obj return obj class MyTest(TestInstance): def test_greet(self): # 调用projectlib中的greet函数 self.lib.libA.greet("namename") print("---------------") self.lib.libA.greetB("namename") if __name__ == '__main__': my_test = MyTest() my_test.test_greet()
标签:__,name,lib,python,self,module,className,加载 From: https://www.cnblogs.com/shunguo/p/18162501