十二:django中间件学习之拓展1

django中间件学习之拓展

拓展模块importlib

# 模块importlib

import importlib
res = 'myfile.b'
ret = importlib.import_module(res)  # from myfile import b
# 该方法最小只能到py文件名
print(ret)
 模块 importlib
能够以字符串的形式帮助你导入模块,但是需要注意最小单位只能到模块名

根据中间件推导出来的重要编程思想

在配置文件中注释或者添加新的字符串实现功能的取消和新增,是一种解耦合非常强的编程思想。

比如,我们在django配置文件settings.py中MIDDLEWARE列表元素的注释增加

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

这类编程思想用到的知识点主要有以下几点:

(1)模块的动态导入(以字符串形式)

(2)反射

(3)鸭子类型(多态)

  • 每一个功能独享一个py文件,放在一个文件夹下
  • 创建一个settings.py配置文件,将需要被导入的模块中的具体对象的路径以字符串的方式写入列表
  • 在存放功能的文件夹下的每个py文件都是一个功能模块,所以该文件夹就是一个包,所以就需要在该文件夹下在创建__init__.py文件,将每一个功能模块的名字都放在该py文件下
  • __init__.py文件中,通过for循环 + 鸭子类型 +字符串方法+反射就可以实现django中settings.py中只需要添加注释或者解除注释就可以实现某种功能的添加或者删除

案例:开放多种支付接口(微信支付,QQ支付,支付宝支付)

  • 目录结构
.
├── notify
│   ├── ali_pay.py
│   ├── __init__.py
│   ├── qq_pay.py
│   └── wechat_pay.py
├── settings.py
└── start.py

notify文件夹

ali_pay.py

class AliPay(object):
    def __init__(self, money):
        """调用支付宝的相关接口"""
        self.money = money
        pass

    def pay(self):
        print('使用支付宝支付%s元' % (self.money,))

qq_pay.py

class QQPay(object):
    def __init__(self, money):
        """调用QQ支付的相关接口"""
        self.money = money
        pass

    def pay(self):
        print('使用QQ支付支付%s元' % (self.money,))

wechat_pay.py

class WeChatPay(object):
    def __init__(self, money):
        """调用微信支付的相关接口"""
        self.money = money
        pass

    def pay(self):
        print('使用微信支付支付%s元' % (self.money,))
__init__.py
import importlib
import settings


def pay_all(money):
    for path_str in settings.NOTIFY_LIST:
        module_path, class_name = path_str.rsplit('.', maxsplit=1)
        # module_path = 'notify.ali_pay'
        # 利用字符串动态导入模块
        module = importlib.import_module(module_path)  # from notify import ali_pay
        # 利用反射动态获取类名
        if hasattr(module, class_name):
            cls = getattr(module, class_name)
            # 实例化一个对象
            obj = cls(money)
            obj.pay()

settings.py

NOTIFY_LIST = [
    'notify.ali_pay.AliPay',
    'notify.qq_pay.QQPay',
    'notify.wechat_pay.WeChatPay'
]

start.py

import notify    # 导入这个包,会自动执行其下面的__init__.py方法

notify.pay_all('1024')

执行start.py
img

原文地址:https://www.cnblogs.com/wait59/p/13945037.html