python中字符串导入模块 importlib介绍

字符串导入模块importlib

# 模块:importlib
import importlib
res = 'myfile.b'
ret = importlib.import_module(res)  # 相当于:from myfile import b
# 该方法最小只能到py文件名
print(ret)

from myfile import b
print(b)

importlib应用场景

# 需求:发送通知的功能,发微信、qq、邮箱,同时通过这三个功能给客户发消息,可以随时禁止某一个板块的通知(只给微信qq发送通知,不给邮箱发)

普通版本:

功能文件:notify.py

# 简单模拟三个功能

def wechat(content):
    print('微信通知:%s'%content)

def qq(content):
    print('qq通知:%s'%content)

def email(content):
    print('email通知:%s'%content)

启动文件:start.py

from notify import *   # 导入所有的函数

def send_all(content):   # 定义一个函数执行所有的功能函数
    wechat(content)
    qq(content)
    email(content)

if __name__ == '__main__':
    send_all('你的特别关心给你发消息了')   # 执行执行函数触发所有的功能函数

高阶版本:

创建一个notify文件夹,下面存储的都是功能模块,那么这就相当于一个包,包就需要有一个__init__.py文件,如果想要找包下面的所有模块的话,就直接通过__init__.py文件即可。

settings.py

NOTIFY_LIST = [
    'notify.email.Email',   # 存储各功能模块的路径
    'notify.qq.QQ',
    'notify.wechat.Wechat',
]

notify文件夹下:wechat.py

class Wechat(object):
    def __int__(self):
        pass   # 发送微信需要做的前期准备

    def send(self,content):
        print('微信通知:%s'%content)

notify文件夹下:qq.py

class QQ(object):
    def __int__(self):
        pass # 发送qq需要做的前期准备

    def send(self, content):
        print('QQ通知:%s' % content)

notify文件夹下:email.py

class Email(object):
    def __int__(self):
        pass # 发送email需要做的前期准备

    def send(self, content):
        print('邮箱通知:%s' % content)

notify文件夹下:_ init_.py

import settings
import importlib

# 定义一个send_all方法
def send_all(content):
    for path_str in settings.NOTIFY_LIST:  # 这样就拿到的是settings下的列表:'notify.email.Email',
        module_path, class_name = path_str.rsplit('.',maxsplit=1)  # 使用字符串右切割:以 . 来切割切一位
        # 这样解压复制:module_path = notify.email   class_name=Email

        # 利用字符串的导入:notify.email
        module = importlib.import_module(module_path)  # 返回的是一个对象
        # 这样就相当于:from notify import email

        # 运用反射:拿到module对象里的class_name(Email)类
        cls = getattr(module,class_name)

        # 生成类的对象
        obj = cls()

        # 利用鸭子类型直接调用send方法
        obj.send(content)

启动文件:start.py

import notify

notify.send_all('特别关心下线了')

posted @ 2022-03-10 15:29  JasonBorn  阅读(265)  评论(0编辑  收藏  举报