开放封闭原则 importlib getattr

Posted fanggege

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开放封闭原则 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常配合使用

 

以上是关于开放封闭原则 importlib getattr的主要内容,如果未能解决你的问题,请参考以下文章

面向对象原则之一 开放封闭原则(开闭原则)

Charpter04 开放-封闭原则

设计原则之开放封闭原则

敏捷开发-开放封闭原则

深入浅出设计模式——开放封闭原则

西游记之设计模式原则——开放-封闭原则