参考中间件配置实现功能插拔式设计
说白了就是想做到想 注释中间件一样,存在的时候,全局都会走那个中间件,不要用的时候注释掉,除了不实现那个功能之外对全局都不会有影响。
这就是可插拔式设计。
首先讲解一个模块 importlib
这个模块的作用:以字符串的形式导入模块
module = 'file.a'
importlib.import_module(module)
上面这句就等于下面这句
from file import a
接下来就可以讲一下可插拔式设计了。
现在我想有三种通知方式,短信通知,邮件通知,微信通知,而且我想禁用哪个,就直接禁用哪个,而不用通过去方法里面一个个的注释掉这个函数。
首先建一个包notify,包里面有四个py文件,__init__.py email.py msg.py wechat.py
然后在根目录下写两个py文件 ,一个是 run.py 一个是settings.py
settings.py
NOTYFY_LIST = [
'notify.email.Email',
'notify.msg.Msg',
'notify.wechat.WeChat',
]
run.py
import notify
notify.send_all('hahahaahaha')
email.py
class Email():
def __init__(self):
pass
def send(self,content):
print('邮件通知:%s'%content)
msg.py
class Msg():
def __init__(self):
pass
def send(self,content):
print('短信通知:%s'%content)
wechat.py
class WeChat():
def __init__(self):
pass
def send(self,content):
print('vx通知:%s'%content)
最重要的一个py文件
import settings
import importlib
def send_all(content):
for module_path in settings.NOTYFY_LIST:
module, class_name = module_path.rsplit('.',maxsplit=1)
mod = importlib.import_module(module)
# 上面这句等于from notify import email
cls = getattr(mod,class_name) #利用反射获取模块种类的变量名
obj = cls()
obj.send(content)
总体讲解:
首先写一个文件夹notify,在这个文件夹里面写了三个py文件,分别用面向对象的方式在每个文件里面写了三个通知的类,每个类都有一个send方法,用来被调用。然后去settings文件里面把这三个类的路径以字符串的形式配置好。
然后,最重要的一步开始了,在notify文件夹里写了一个__init__.py文件,这就让这个文件夹变成了包。导入这个包的东西,就只用导入这个init就行。前提是在init里面吧那三个py文件导入了先。
在init 里导入了settings里的配置好的字符串路径,循环这个字符串列表,然后通过这句module, class_name = module_path.rsplit('.',maxsplit=1) 切片,module拿到的就是notify.email ,class_name拿到的就是Email
然后通过importlib.import_module(module),得到的结果就是那个模块,在这里也就是email模块。 然后又通过反射,获取在这个模块里的类的变量名,用cls来接收,循环的第一次就是 Email这个类,然后obj = cls()实例化生成了一个对象,obj.send(content)就执行了他的方法,打印了一条结果,settings里配置了几个,就打印几个结果。当然我们要运行的文件是 run文件,run里面就只用导入这个包,就相当于导入了这个包的 init 文件,直接notify.send_all('输出我要输入的字符') 就行了。
这样一来就实现了可插拔式设计,代码不重要,重要的是这个思想。
原文地址:https://www.cnblogs.com/chanyuli/p/11773988.html
- javascript深入理解js闭包
- https连接的前几毫秒发生了什么
- android自定义view实现progressbar的效果
- 还是不靠谱!多维LSTM网络预测比特币价格【机器学习应用区块链系列二】
- picasso图片缓存框架
- Git基础和规范-协同开发
- JavaScript 知识点梳理 | 从基础语法到高级用法
- Java正则速成秘籍(一)之招式篇
- Rafy 框架 - 使用 SqlTree 查询
- 详细讲解Quartz.NET
- android AlarmManager讲解
- Intent和PendingIntent的区别
- android程序崩溃后重启
- jQuery源码——.html()方法原理解析
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 10.深入k8s:调度的优先级及抢占机制源码分析
- redis
- synchronized底层是怎么实现的?
- RSA
- Syncd - 开源自动化部署工具
- pointer-events:none禁用鼠标事件
- TiCDC 首个 GA 版本发布,特性与场景全揭秘
- Linux远程ssh执行命令expect使用及几种方法
- 数据结构--线性表和链表的基础知识
- Salesforce LWC学习(二十五) Jest Test
- 自建npm包-搭建,打包,调试,发布
- 你对排序算法了解多少
- 【大数据架构】大数据数据仓库与数据中台架构
- JavaScript中的内置对象、面向对象与原型
- Java.lang.Illegalaccessexception 或 java.lang.NoSuchMethodError