
本文介绍一种通过 importlib 和正则表达式动态筛选并导入指定命名模式变量的方法,避免使用 import * 或手动列举,适用于含数百个变量的大型配置场景。
本文介绍一种通过 `importlib` 和正则表达式动态筛选并导入指定命名模式变量的方法,避免使用 `import *` 或手动列举,适用于含数百个变量的大型配置场景。
在 Python 中,标准的 import 语句不支持正则表达式语法(如 from script_load import r'^COLOUR.+$'),因此直接在 import 语句中嵌入正则会触发 SyntaxError。但我们可以借助 importlib 动态加载模块,并结合 re 模块筛选变量名,再将匹配的变量注入当前模块的全局命名空间(globals()),从而实现“按模式导入”的效果。
以下是一个完整、安全、可复用的实现方案:
import importlib
import re
def dynamic_import(pattern: re.Pattern, module_name: str) -> None:
"""
根据正则表达式 pattern,从指定模块中导入所有匹配的变量到当前全局作用域。
Args:
pattern: 编译后的正则对象(推荐使用 re.compile 预编译以提升性能)
module_name: 模块名(字符串形式,如 'script_load')
"""
try:
module = importlib.import_module(module_name)
except ImportError as e:
raise ImportError(f"无法导入模块 '{module_name}': {e}") from e
# 遍历模块所有公有属性(跳过私有属性和内置属性)
for attr in dir(module):
if not attr.startswith('_'): # 排除 _ 开头的私有/特殊属性
if pattern.match(attr):
globals()[attr] = getattr(module, attr)
# 清理临时引用,减少内存占用
del module
# 使用示例:仅导入 script_load 中以 "COLOUR_" 开头的变量
dynamic_import(re.compile(r'^COLOUR_.*$'), 'script_load')
# 现在可直接使用这些变量(无需前缀)
print(COLOUR_ONE, COLOUR_TWO, COLOUR_THREE) # ✅ 正常输出
# print(BUILDING_ONE) # ❌ NameError:未导入 BUILDING_* 变量
⚠️ 重要注意事项:
-
命名冲突风险:若当前模块已存在同名变量,
globals()[attr] = ...将覆盖原有值,请确保目标变量名唯一; -
作用域限制:该方法仅影响调用位置所在模块的全局作用域(即
script_main.py的顶层globals()),不适用于函数内部(除非显式操作globals()); -
性能考量:
dir(module)会列出所有属性(包括方法、类等),建议配合not attr.startswith('_')过滤,提高准确性和效率; -
可维护性建议:对于长期项目,更推荐重构为显式导出(如在
script_load.py中定义__all__ = ['COLOUR_ONE', 'COLOUR_TWO', ...])或封装为配置类,但本方案在快速适配遗留代码时极为实用。
总结而言,虽然 Python 不原生支持正则导入,但通过 importlib + re + globals() 的组合,我们能以简洁、可控的方式实现精准变量注入——尤其适合处理大量配置变量且需按前缀/模式分组使用的工程场景。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











