# testInstance.py # 导入需要的模块 import importlib # 导入模块以动态加载库中的类和函数 import sys # 导入系统模块,用于操作Python解释器的参数和变量 import os import pkgutil # 定义TestInstance类 class TestInstance: # 初始化方法,当创建TestInstance对象时调用 def __init__(self, projectName): # 初始化实例变量projectName,存储项目名称 self.projectName = projectName # 调用load_libraries方法加载库,并将结果存储在self.lib中 self.lib = self.load_libraries() # 定义load_libraries方法,用于加载库 def list_submodules(self,package_path): """递归地列出给定包路径下的所有子模块""" all_submodules = [] # 遍历包路径下的所有文件/目录 for importer, modname, ispkg in pkgutil.iter_modules([package_path]): full_modname = modname module_path = os.path.join(package_path, modname) # 如果是子包,则递归调用list_submodules if ispkg: # 构建子包的完整路径 subpackage_path = os.path.join(module_path, '__init__.py') # 递归查找子包下的子模块 submodules = self.list_submodules(subpackage_path) # 添加子模块名称到结果列表,同时保留子包的路径 all_submodules.extend([full_modname + '.' + submodule for submodule in submodules]) else: # 添加非包模块的完整名称 all_submodules.append(full_modname) return all_submodules def load_libraries(self): # 导入配置模块 import libconfig # 假设存在一个名为libconfig的模块,其中包含库的加载顺序等信息 # 初始化一个空字典,用于存储库中的类和函数 libraries = {} # 将库路径添加到sys.path,以便Python能够找到这些库 # sys.path.append(r"C:\Users\15773\Desktop\文心一言\新建文件夹\test_library\projectLib") # 添加项目库路径 # sys.path.append(r"C:\Users\15773\Desktop\文心一言\新建文件夹\test_library\commonLib") # 添加通用库路径 print("sys.path",sys.path) # 按照配置模块中指定的顺序加载库 root = r"C:\Users\15773\Desktop\文心一言\新建文件夹\test_library" for lib_name in libconfig.libraries_order: # 遍历库名列表 # sys.path.insert(0,os.path.join(root, lib_name)) libPath = os.path.abspath(os.path.join(root, lib_name)) print("libPath",libPath,lib_name) allPac = self.list_submodules(libPath) print("allPac",allPac) # 动态导入库模块 for library in allPac: print("library",library) module = importlib.import_module(library) # 使用importlib导入库模块 print("-----",dir(module)) print("module.__file__",module.__file__) print([attr_name for attr_name in dir(module) if not attr_name.startswith('_')]) # 将库模块中的非私有属性和方法添加到libraries字典中 libraries.update( {attr_name: getattr(module, attr_name) for attr_name in dir(module) if not attr_name.startswith('_')}) print("libraries",libraries) # 创建一个类似命名空间的类,用于持有所有库中的类和函数 class LibraryNamespace: # 定义__getattr__方法,当尝试访问不存在的属性时调用 def __getattr__(self, item): print("--item",item) # 首先检查项目库中是否存在该属性 if item in libraries: print("item in lib-------------",item,libraries) # return libraries[item] # 如果存在,直接返回对应的类或函数 tempInstance = libraries[item]() # 如果存在,直接返回对应的类或函数 return tempInstance # 如果在项目库中找不到,尝试从commonlib库中导入 commonlib_module = importlib.import_module(f"commonlib.{item}") # 动态导入commonlib中的模块或函数 tempInstance = commonlib_module() print("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&") # return getattr(commonlib_module, item) # 返回commonlib中的类或函数 return getattr(tempInstance, item) # 返回commonlib中的类或函数 # 创建一个LibWrapper类,用于包装LibraryNamespace,并为其添加一个lib属性 class LibWrapper: def __init__(self, namespace): # print("namespace",namespace) # 在LibWrapper实例初始化时,将LibraryNamespace实例赋值给lib属性 self.lib = namespace # 返回LibWrapper的实例,其中包含了LibraryNamespace # return LibWrapper(LibraryNamespace()) # print("namespace",LibraryNamespace) return LibraryNamespace() # 如果该脚本被直接执行(而不是作为模块导入),则执行以下代码 if __name__ == '__main__': # 假设当前项目名称为"projectlib" projectName = "projectA" # 创建TestInstance对象 test = TestInstance(projectName) # print("test.lib",test.lib) # 调用lib.libA.greet方法,并传递参数"world" # 由于使用了__getattr__,即使libA或greet不存在,也不会立即抛出异常,而是会尝试从commonlib中导入 print(test.lib.libA.greet("hello world")) print(test.lib.libA.greetB("BBB"))
标签:__,lib,python,module,libraries,print,path,加载 From: https://www.cnblogs.com/shunguo/p/18064756