21 参考中间件,实现可插拔式设计

[TOC]python

1、前言

什么是可插拔式设计?django

在咱们前面学习的django的内容,在django框架中,咱们学习到了中间件,中间件是干吗的,都还记得把!!微信

中间件是当请求来的时候,全局的对每个request进行一个验证,咱们都知道在Django的中间件中,有7个默认的中间件,而当一个request来的时候,这个request要依次通过每个中间件的校验,当这个request对应的response走的时候,又要按照中间件列表的顺序进行倒叙执行中间件框架

在咱们最开始用form表单提交数据的时候,咱们好像是要把一个叫csrf的中间件给注释掉,而后form表单才能去提交post请求,也就是说当注释掉这个叫csrf的中间件的时候,request请求来的时候,这个request就不会通过这个中间件的校验了,而当咱们把这个csrf的中间件注释解开的时候,咱们发现request请求有通过这个中间件的校验了。<font color=red>这就叫可插拔式设计</font>post

2、可插拔式须要用到的方法

1. 可插拔式设计的代码,必定要是面向对象的
2.用到一个
3.用到反射getattr()

3、实例

咱们如今有一个公司,如今公司有一个需求,由于今天是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('开开心心')
相关文章
相关标签/搜索