前言
所谓开放封闭原则即:开放配置、封闭源码。例如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' #数据采集的模式配置
根据配置,获取对应插件代码
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() #数据采集执行
总结
传统的模块导入为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常配合使用