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中的函数将被调用。

posted @ 2024-03-03 22:06  朵朵奇fa  阅读(46)  评论(0编辑  收藏  举报