Keeping up with the django - 插拔式设计 | Python 主题月

本文正在参加「Python主题月」,详情查看 活动连接前端

微信公众号搜索【程序媛小庄】 - 没有白走的路,每一步都算数python

前言

在django全栈项目中,前端向后端提交post请求时须要注释csrf校验,将代码注释以后就无需进行校验了,如何实现只注释一行代码就能够注释掉整个功能呢?本文将介绍插拔式设计是如何实现的?web

插拔式设计

插拔式设计实现须要借助一个模块importlib,该模块能够将字符串类型的路径转换为导入模块的语法格式。django

# 导入模块的常规写法
from module import object

# 使用importlib
import importlib
res = 'myfile.test'
ret = importlib.import_module(res)  # from myfile import b
复制代码

能够经过这种代码设计方式模拟一下通知消息,简约版微信 QQ 短信等同时发送,而且能够很方便的关闭某一种通知渠道。后端

方式一:常规思路微信

建立一个py文件,将每一个功能定义为一个函数,再建立一个启动文件,将定义的功能导入,在启动文件中运行。markdown

myfile文件夹
- notify.py

def wechat(content):
    print(f'微信通知:{content}')


def message(content):
    print(f'短信通知:{content}')

def qq(content):
    print(f'qq通知{content}')
    
    
- start.py
import notify

def send(content):
    notify.wechat(content)
    notify.message(content)
    notify.qq(content)

if __name__ == '__main__':
    send('下课啦')
复制代码

方式二:面向对象函数

  • 借鉴django中间件的思路,每一个功能独享一个py文件,所有放在一个目录下。
  • 建立一个settings.py配置文件,将须要被导入的模块中的具体对象的路径以字符串的方式写入列表。
  • 在存放功能的文件夹下的每一个py文件都是一个功能模块,因此该文件夹就是一个包,因此就须要在该文件夹下在建立__init__.py文件,将每个功能模块的名字都放在该py文件下
  • __init__.py文件中,经过for循环 + 鸭子类型 +字符串方法+反射就能够实现django中settings.py中只须要添加注释或者解除注释就能够实现某种功能的添加或者删除
# notify文件夹就是包
- email.py

class Email():
    def __init__(self):
        # 调用应用接口
        pass
    def send(self,content):
        print(f'email{content}')
        
- qq.py
class QQ():
    def __init__(self):
        # 调用应用接口
        pass
    def send(self,content):
        print(f'qq{content}')
        
-wechat.py
class Wechat():
    def __init__(self):
        # 调用应用接口
        pass
    def send(self,content):
        print(f'wechat{content}')
    

- settings.py

NOTIFY_LIST = [
    'notify.email.Email',
    'notify.qq.QQ',
    'notify.wechat.Wechat'
]

- __init__.py

import settings
import importlib


def send_all(content):
    for path_str in settings.NOTIFY_LIST:  #'notify.email.Email'
        module_path,class_name = path_str.rsplit('.',maxsplit=1)
        # module_path = 'notify.email' class_name = 'Email'
        # 1 利用字符串导入模块
        module = importlib.import_module(module_path)  # from notify import email
        # 2 利用反射获取类名
        cls = getattr(module,class_name)  # Email、QQ、Wechat
        # 3 生成类的对象
        obj = cls()
        # 4 利用鸭子类型直接调用send方法
        obj.send(content)
        
        
- start.py

import notify
if __name__ == '__main__':
    notify.send_all('haha')
复制代码

结语

文章首发于微信公众号程序媛小庄,同步于掘金post

码字不易,转载请说明出处,走过路过的小伙伴们伸出可爱的小指头点个赞再走吧(╹▽╹)ui

image.png

相关文章
相关标签/搜索