[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('開開心心')