python加载库
# testInstance.py # 导入需要的模块 import importlib # 导入模块以动态加载库中的类和函数 import sys # 导入系统模块,用于操作Python解释器的参数和变量 # 定义TestInstance类 class TestInstance: # 初始化方法,当创建TestInstance对象时调用 def __init__(self, projectName): # 初始化实例变量projectName,存储项目名称 self.projectName = projectName # 调用load_libraries方法加载库,并将结果存储在self.lib中 self.lib = self.load_libraries() # 定义load_libraries方法,用于加载库 def load_libraries(self): # 导入配置模块 import libconfig # 假设存在一个名为libconfig的模块,其中包含库的加载顺序等信息 # 初始化一个空字典,用于存储库中的类和函数 libraries = {} # 将库路径添加到sys.path,以便Python能够找到这些库 sys.path.append("library/commonlib") # 添加通用库路径 sys.path.append("library/projectlib") # 添加项目库路径 # 按照配置模块中指定的顺序加载库 for lib_name in libconfig.libraries_order: # 遍历库名列表 # 动态导入库模块 module = importlib.import_module(lib_name) # 使用importlib导入库模块 # 将库模块中的非私有属性和方法添加到libraries字典中 libraries.update({attr_name: getattr(module, attr_name) for attr_name in dir(module) if not attr_name.startswith('_')}) # 创建一个类似命名空间的类,用于持有所有库中的类和函数 class LibraryNamespace: # 定义__getattr__方法,当尝试访问不存在的属性时调用 def __getattr__(self, item): # 首先检查项目库中是否存在该属性 if item in libraries: return libraries[item] # 如果存在,直接返回对应的类或函数 # 如果在项目库中找不到,尝试从commonlib库中导入 commonlib_module = importlib.import_module(f"commonlib.{item}") # 动态导入commonlib中的模块或函数 return getattr(commonlib_module, item) # 返回commonlib中的类或函数 # 创建一个LibWrapper类,用于包装LibraryNamespace,并为其添加一个lib属性 class LibWrapper: def __init__(self, namespace): # 在LibWrapper实例初始化时,将LibraryNamespace实例赋值给lib属性 self.lib = namespace # 返回LibWrapper的实例,其中包含了LibraryNamespace return LibWrapper(LibraryNamespace()) # 如果该脚本被直接执行(而不是作为模块导入),则执行以下代码 if __name__ == '__main__': # 假设当前项目名称为"projectlib" projectName = "projectlib" # 创建TestInstance对象 test = TestInstance(projectName) # 调用lib.libA.greet方法,并传递参数"world" # 由于使用了__getattr__,即使libA或greet不存在,也不会立即抛出异常,而是会尝试从commonlib中导入 print(test.lib.libA.greet("world"))
# testInstance.py import importlib import sys class TestInstance: def __init__(self, projectName): self.projectName = projectName self.lib = self.load_libraries() def load_libraries(self): # Import the configuration module import libconfig libraries = {} # Append the library paths to sys.path sys.path.append("library/commonlib") sys.path.append("library/projectlib") # Load libraries in the specified order for lib_name in libconfig.libraries_order: # Import the library module module = importlib.import_module(lib_name) # Add the module's attributes to the libraries dict libraries.update({attr_name: getattr(module, attr_name) for attr_name in dir(module) if not attr_name.startswith('_')}) # Create a namespace-like object to hold the classes/functions from all libraries class LibraryNamespace: def __getattr__(self, item): # First check if the attribute exists in the current project's libraries if item in libraries: return libraries[item] # If not found, check commonlib commonlib_module = importlib.import_module(f"commonlib.{item}") return getattr(commonlib_module, item) # Return the namespace object return LibraryNamespace() # Example usage if __name__ == '__main__': # Assume the current project name is "projectlib" projectName = "projectlib" test = TestInstance(projectName) # Call greet function from libA without explicitly checking for its existence # The framework handles the fallback logic if the function is not found in the project's library print(test.libA.greet("World"))
在这个修改后的代码中,load_libraries
方法现在将所有库的属性合并到一个字典中,而LibraryNamespace
类则覆盖了__getattr__
方法以处理属性的动态查找。当尝试访问test.libA.greet
时,如果greet
函数在项目的库中不存在,__getattr__
方法会尝试从commonlib
库中导入libA
模块并获取greet
函数。
这意味着,脚本中不需要进行任何显式的检查来确定函数的位置。当调用test.libA.greet("World")
时,如果函数在项目库中不存在,框架将自动回退到commonlib
库并尝试调用该函数。
请确保libconfig.libraries_order
列表中的库加载顺序符合你的要求,即项目库应该在commonlib
之前,这样项目库中的函数将优先被调用。如果项目库中没有找到函数,那么commonlib
中的函数将被调用。