[TOC]python
什么是可插拔式设计?django
在咱们前面学习的django的内容,在django框架中,咱们学习到了中间件,中间件是干吗的,都还记得把!!微信
中间件是当请求来的时候,全局的对每个request进行一个验证,咱们都知道在Django的中间件中,有7个默认的中间件,而当一个request来的时候,这个request要依次通过每个中间件的校验,当这个request对应的response走的时候,又要按照中间件列表的顺序进行倒叙执行中间件框架
在咱们最开始用form表单提交数据的时候,咱们好像是要把一个叫csrf的中间件给注释掉,而后form表单才能去提交post请求,也就是说当注释掉这个叫csrf的中间件的时候,request请求来的时候,这个request就不会通过这个中间件的校验了,而当咱们把这个csrf的中间件注释解开的时候,咱们发现request请求有通过这个中间件的校验了。<font color=red>这就叫可插拔式设计</font>post
1. 可插拔式设计的代码,必定要是面向对象的 2.用到一个 3.用到反射getattr()
咱们如今有一个公司,如今公司有一个需求,由于今天是10月的最后一天,公司准备给每个工做人员经过qq、手机短信、微信的方式,给工做人员发三太难短信,学习
而后,到11月份的月底,公司只想经过微信,qq的方式来发送信息了,这该怎么样设计一个可插拔是的程序呢?---根据django中间件的思想spa
1.咱们先用面向对象来写着三个发消息的共功能 # 面向对象的鸭子类型 # 只要长得像,就是鸭子类型 # 就是有不少个类,可是这些个类都具备一样的方法名,可是呢?它的方法名实现的功能不同,就是鸭子类型 # QQ 消息 class QQ: # 实例化类的时候触发 def __init__(self,name): self.name = name # 对象的绑定方法 # 也是鸭子类型的方法 def send_msg(self,content): print('QQ今天是10月的最后一天,请好好{}'.format(content)) # 微信 消息 class Wechat: # 对象实例化的时候触发 def __init__(self,name): self.name = name # 鸭子类型的方法,对象的绑定方法 def send_msg(self,content): print('Wechat今天是10月的最后一天,请好好{}'.format(content)) # Phone 短信 class Phone: def __init__(self,name): self.name = name # 鸭子类型 def send_msg(self,content): print('Phone今天是10月的最后一天,请好好{}'.format(content))
从上面咱们写的类中,三种发送消息的类,能够看到send_msg就是鸭子类型的方法,设计
咱们将上面的每个类都放在不一样的.py文件里code
<font color=red>为何放在一个包里呢?由于在settings配置里面。咱们要导入这几个文件,导入一个文件他就是一个模块,那做为一个模块,固然要放在包里了,__init__.py文件里,from msg_bag import *
</font>orm
那这三个类都写好了,咱们知道django中间件是则settings里配置了一个列表,这个列表就是放着一个个字符串一行的类,
那这里,咱们也将这三个类放在setting文件中,固然首先的本身新建一个settings配置文件啦
# settings.py FUNC_LIST = [ 'msg_bag.phone.Phone', 'msg_bag.qq.QQ', 'msg_bag.wechat.Wechat', ]
# 启动文件 import setting # 将配置文件导进来 import importlib # 将这个模块导入 def run(content): # 循环settings配置文件里的类的模块列表 ''' FUNC_LIST = [ 'msg_bag.phone.Phone', 'msg_bag.qq.QQ', 'msg_bag.wechat.Wechat', ''' for func in setting.FUNC_LIST: # 将每个字符串拿出来,而后根据.切割,从末尾切割一个 model,class_name = func.rsplit('.',maxsplit=1) print(model) # msg_bag.phone \ msg_bag.qq \ msg_bag.wechat print(class_name) # Phone \ QQ \ Wechat # 利用importlib模块 mod = importlib.import_module(model) ''' 等同于 form msg_bag import phone form msg_bag import qq form msg_bag import wechat ''' # 经过反射class_name是否是mod的类,而后取值赋给class_obj class_obj = getattr(mod, class_name) # 经过类去调用对象的绑定方法,将类本身传给send_msg class_obj.send_msg(class_obj,content) run('开开心心')