importlib 模块

作用:

以字符串的形式导入模块,拿到的是能够访问当前模块名称空间的名字

使用:

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)  # 
print(module.NAME)  # shanghai
res = gatatter(module, NAME)
print(res)  # shanghai

importlib 模块_第1张图片

补充:

  1. 一个py文件可以看做是一个模块
  2. 模块有模块的名称空间,里面存放的是该模块内 对应 类,函数,变量值内存地址的 名
  3. 可以利用反射getatter(module, 方法名) 拿到对应的方法

案例: 

利用importlib实现配置文件的插拔式功能,实现'扩展封闭'和'解耦合'

  • settings.py

importlib 模块_第2张图片

  • 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()

 

你可能感兴趣的:(importlib 模块)