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('特别关心下线了')