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('開開心心')
相關文章
相關標籤/搜索