开放封闭原则 、importlib getattr

前言

所谓开放封闭原则即:开放配置、封闭源码。例如django 中间件的插拔特性配置

CMDB 中不同模式下(agent/ssh/salt)采用不同的数据采集方法,每个方法定义成一个单独的插件脚本。通过读取settings.py 配置觉得执行那种插件,通过配置settings.py 扩展模式类型。

config/settings.py 配置文件代码

ENGINE_HANDLERS = {     #不同模式对应的采集插件配置,可以后期扩展
    'agent':'src.engine.agent.AgentHandler',
    'ssh':'src.engine.ssh.SSHHandler',
    'salt':'src.engine.salt.SaltHandler',
}
ENGINE = 'agnt'         #数据采集的模式配置
View Code

根据配置,获取对应插件代码

import importlib
from config import settings
from lib.module_string import import_string
def run():
    """
    采集资产的入口
    :return:
    """
    # 'src.engine.agent.AgentHandler'
    engine_path = settings.ENGINE_HANDLERS.get(settings.ENGINE) #获取配置文件中的模式配置settings.ENGINE,通过它获取模块
    
    cls = import_string(engine_path)                            #模块导入代码封装在import_string 中了
    
    module_path,cls_name = engine_path.rsplit('.',maxsplit=1)  #rsplit 对字符串从右边第一个点分割一次
    module = importlib.import_module(module_path)              #importlib.import_module 根据变量或字符串导入模块,传统的import 后面参数必须为模块
    cls = getattr(module,cls_name)                               #从模块中导入类
    obj = cls()                                                #实例化
    obj.handler()                                               #数据采集执行
View Code

总结

传统的模块导入为import  module_name  module_name 为模块名,此模块名字不是字符串也不是变量,变量定义时不可以与已经存在的模块名突出,所以import 导入的模块方式就是通过模块导入模块

importlib.import_module(module_path)   import_module 通过变量或者字符串作为参数导入模块,参数必须为变量或字符串不可以为模块名字。而且只能导入模块也就是Py 文件,不可以导入模块内的类或者函数的变量

cls = getattr(module,cls_name)          getattr() 与import_module 相似也只能通过变量或者字符串识别模块来导入模块(py文件)中的类/函数/变量等,它与import_module常配合使用

猜你喜欢

转载自www.cnblogs.com/fanggege/p/10261583.html