发布时间:2023-05-21 10:30
1. Django的settings配置文件中的中间件编写方式如下所示
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\',
]
2. 我们可以将其看作是列表中包含了多个字符串,但是字符串的作用其实类似于模块,如下示例
from django.middleware.security import SecurityMiddleware
3. 如果我们也想实现将一个个模块变成字符串的导入形式,就需要使用到一个叫做 \'importlib\' 的模块
该模块可以通过字符串的形式导入模块
常规导入方式
from b import c
结果如下图所示,打印模块的结果是:
<module \'b.c\' from \'F:\\\\python project\\\\pythonProject_importlib\\\\b\\\\c.py\'>
字符串导入方式
import importlib
# 创建字符串
module_path = \'b.c\'
# 以字符串形式导入
res = importlib.import_module(module_path)
print(res)
结果如下图所示,打印的结果和普通导入的一致
俩者区别
1. 普通导入方式可以导入文件中指定的对象,如下所示
from b.c import name
print(name)
2. 而字符串的方式最小导入单位是模块文件级别,如下示例的情况会报错
import importlib
module_path = \'b.c.name\'
res = importlib.import_module(module_path)
print(name)
用打印信息功能作为案例来比较,首先先使用普通函数的形式。
普通编写方式
在这种情况下,将功能封装到函数里,若是不想某单个函数执行直接在总函数里删除即可。
封装成配置
类似于settings文件的格式,封装成配置
1. 首先创建一个包,在包中创建多个py文件,每个py文件中均有一个类,类中均定义了send方法,使其符合多态性,例如
class QQ(object):
def __init__(self):
pass
# 定义send方法
def send(self, info):
print(\'qq\', info)
2. 在settings.py文件中创建列表用于存放字符串路径,用点的方式指向最终的类,如下示例
NOTIFY_FUNC_LIST = [
\'notify.qq.QQ\',
\'notify.weibo.WeiBo\',
\'notify.weixin.WeiXin\',
]
3. 在notify包中的双下init文件中编写表示全部send方法的函数,如下示例
# 导入settings文件用于获取路径字符串
import settings
# 使用字符串形式导入,需要导入importlib
import importlib
# 创建send的总函数
def send_all(info):
# 循环获取配置文件中的字符串,格式为 \'notify.qq.QQ\'
for str_path in settings.NOTIFY_FUNC_LIST:
# 从右边开始切割字符串路径,并设定最大切割次数为1,切割完结果类似于 [\'notify.qq\', \'QQ\']
module_str_path, class_str_name = str_path.rsplit(\'.\', maxsplit=1)
# 导入切割后的字符串路径,类似于 notify.qq
module = importlib.import_module(module_str_path)
# 使用反射方法,获取模块中的类,getattr(x, \'y\') 等价于 x.y
class_name = getattr(module, class_str_name)
# 实例化模块中的类
obj = class_name()
# 调用发送信息的功能,由于发送消息的方法都叫做send,所以均可以被调用
obj.send(info)
4. 然后还要在start.py文件中执行包中的函数,如下示例
# 需要先导入包,相当于导入了包中的__init__.py文件
import notify
if __name__ == \'__main__\':
# 执行发送消息的总方法
notify.send_all(\'你好啊\')
5. 以上的步骤结束后,会执行所有在settings文件中配置好的路径中的方法,需要注意的是多态性。如果不想执行某个py
文件中的类方法时,只要在配置文件settings中删除该路径即可,这里只表达编写思想,可以使用别的案例替换。