作用:
以字符串的形式导入模块,拿到的是能够访问当前模块名称空间的名字
使用:
conf文件夹下的settings.py:
NAME = 'shanghai'
test.py文件:
1.普通模块导入:
from conf import settings
print(settings.NAME) # shanghai
2.importlib:
import importlib # 以字符串的形式导入模块,拿到的是能够访问当前模块名称空间的名字
res = 'conf.settings'
module = importlib.import_module(res)
print(module) # <module 'conf.settings' from 'D:\\OldBoy-py\\模块\\importlib模块\\conf\\settings.py'>
print(module.NAME) # shanghai
res = gatatter(module, NAME)
print(res) # shanghai
补充:
- 一个py文件可以看做是一个模块
- 模块有模块的名称空间,里面存放的是该模块内 对应 类,函数,变量值内存地址的 名
- 可以利用反射getatter(module, 方法名) 拿到对应的方法
案例:
利用importlib实现配置文件的插拔式功能,实现'扩展封闭'和'解耦合'
- settings.py
- message/base.py
class Base(object):
"""
该类是用来控制其子类的规范:必须实现send方法
"""
def send(self, msg):
raise NotImplemented
- message/email.py msg.py wechat.py
email.py:
from .base import Base
class Email(Base):
def send(self, msg):
print('email send %s' %msg)
msg.py:
from .base import Base
class Msg(Base):
def send(self, msg):
print('msg send %s' %msg)
wechat.py:
from .base import Base
class Wechat(Base):
def send(self, msg):
print('wechat send %s' %msg)
- message/__init__.py
import settings
import importlib
def send_msgs(msg):
1. 循环MSE_LIST列表,拿到email,msg,wechat的路径
for path in settings.MSG_LIST:
2. 切分拿到路径和功能类
module, cls = path.rsplit('.', 1)
3. 导入字符串形式路径的模块
md = importlib.import_module(module)
4. 实例化功能类
obj = getattr(md, cls)() # 注意; 模块也是对象
5. 调用方法
obj.send(msg)
- app.py
from flask import Flask
from utils.message import send_msgs
app = Flask(__name__)
@app.route('/')
def tool(msg):
send_msgs(msg)
return '%s 发送成功' %msg
tool('error')
if __name__ == '__main__':
app.run()