Python系列 52 内置模块:importlib

importlib简介

importlib模块作为Python内置模块,提供了更多导入模块的方式。

官方文档

常用方法:

  • importlib.import_module(str):根据字符串导入1个模块,该字符串以.为路径分割,如"package.module"

项目示例

假设我的项目之中包含了多个中间件,并且这些中间件会在项目正式启动之前先行启动。

我该如何集中式的管理这些中间件,让它们在需要的时候能够快速加上,不需要的时候能够快速去除呢?

使用importlib模块是最明智的选择,整个项目目录如下:

PYTHONPROJECT
│
├─bin
│  |  run.py
│
├─middleware
│  │  first_middle.py
│  │  init.py
│  │  second_middle.py
│  │  __init__.py
│
├─view
│   │  main.py
│  
│  settings.py

首先先查看一下run.py,它主要处理项目模块路径、中间件初始化以及主程序的运行:

# run.py

import os
import sys

BASE_DIR =  os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)

from middleware.init import init
from view.main import main

if __name__ == "__main__":
    # init middleware
    init()
    # run main
    main()

再来看一下中间件的启动,它会从配置文件中拿到被集中化管理的需要启动的中间件,然后利用importlib模块对其进行导入后执行其下的某一个方法:

# middleware/init.py

import importlib
import settings

def init():
    for stringPath in settings.LOAD_MIDDLEWARE:
        modulePath, funcName = stringPath.rsplit(".", maxsplit=1)
        # 利用importlib模块根据字符串路径导入模块
        module = importlib.import_module(modulePath)
        # 模块也是对象,所以利用反射拿到函数对象并执行
        funcObject = getattr(module, funcName)
        funcObject()

被集中管理的需要加载的中间件被定义在了settings.py的1个列表中。

其中每条数据项代表1个需要被加载的中间件,以BASE_DIR为准,用.进行分割,确定了中间件的导入路径与运行函数:

# settings.py

LOAD_MIDDLEWARE = [
    "middleware.first_middle.m1",
    "middleware.second_middle.m2"
]

当后续需要新增中间件,只需要在middleware包中添加好.py文件并且在settings.py中按照格式把路径和运行函数填入即可。

如果要取消某个中间件的加载,直接在列表中对它进行注释即可。

总结2点:

  • 如何规定模块导入的格式,参见LOAD_MIDDLEWARE列表
  • 如何使用importlib快速导入模块且执行模块下的某一个函数,参见init.py文件

把其他代码也补上吧,中间件的启动函数:

# middleware/first_middle.py
def m1():
    print("middleware 1 run..")
    
# middleware/second_middle.py
def m2():
    print("middleware 2 run..")

主程序函数:

# view/main.py

def main():
    print("view main run...")

运行结果:

middleware 1 run..
middleware 2 run..
view main run...
上一篇:Siri Shortcut


下一篇:importlib 与__import__的区别