Python 中如何根据名字(或路径)动态导入模块?

Python 动态导入模块用 importlib.import_module("模块名");按文件路径导入用 importlib.util.spec_from_file_location。本文介绍各种动态导入方式。

最佳实践
Python 中如何根据名字(或路径)动态导入模块?封面

按模块名动态导入用 importlib.import_module("itertools")——等价于 import itertools,但模块名可以是字符串变量。按文件路径导入用 importlib.util.spec_from_file_location 系列函数。

按模块名导入

import importlib

itertools = importlib.import_module('itertools')
# 等价于 import itertools,但名字可以是运行时确定的字符串

# 导入子模块
json = importlib.import_module('os.path')

检查模块能否导入(不实际导入)

import importlib.util

spec = importlib.util.find_spec('itertools')
if spec is not None:
    print("可以导入")

按文件路径导入

import importlib.util
import sys

spec = importlib.util.spec_from_file_location("my_module", "/path/to/my_module.py")
module = importlib.util.module_from_spec(spec)
sys.modules["my_module"] = module
spec.loader.exec_module(module)

适合插件系统——从任意目录加载 .py 文件作为模块。

典型场景:插件加载

# 加载 plugins/ 目录下所有 .py 文件作为插件
import importlib
import pkgutil
import plugins

for _, name, _ in pkgutil.iter_modules(plugins.__path__):
    module = importlib.import_module(f'plugins.{name}')
    module.register()   # 调用插件的注册函数

常见问题(FAQ)

Q:import() 和 importlib.import_module() 有什么区别?
A:__import__ 是底层函数,对带点的名字返回顶层包而非子模块,行为反直觉;import_module 是官方推荐的高层接口。

Q:动态导入的模块能热更新吗?
A:用 importlib.reload(module) 可以重新加载已导入的模块,但已有的类实例不会自动更新,生产环境慎用。

Q:导入失败怎么处理?
A:包一层 try/except ImportError,插件场景下某个插件加载失败不应影响主程序。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台