如何区分Python模块中导入的对象与自定义对象并获取其来源模块?
解决从模块中提取导入模块列表的问题
针对你遇到的场景(无法通过inspect.getmodule()获取基本类型的导入来源),推荐通过**分析模块的抽象语法树(AST)**来提取导入关系——因为基本类型导入时是值的副本,无法从实例本身追溯来源,只能从源码的导入语句入手,这是最可靠的方式。
实现步骤
- 获取目标模块的源码文本
- 解析源码生成AST树
- 遍历AST树,提取所有
import和from ... import ...语句中的来源模块 - 去重后得到最终的导入模块列表
代码示例
import ast import inspect def extract_imported_modules(target_module): imported_modules = set() # 获取目标模块的源码 source_code = inspect.getsource(target_module) # 解析生成AST ast_tree = ast.parse(source_code) # 遍历AST节点 for node in ast.walk(ast_tree): # 处理普通import语句(如import a) if isinstance(node, ast.Import): for alias in node.names: # 处理子模块(如import a.b.c时,提取根模块a) root_module = alias.name.split('.')[0] imported_modules.add(root_module) # 处理from...import语句(如from a import CONSTANT) elif isinstance(node, ast.ImportFrom): if node.module: root_module = node.module.split('.')[0] imported_modules.add(root_module) return imported_modules # 使用示例 import b print(extract_imported_modules(b)) # 输出: {'a'}
补充说明
- 为什么
inspect.getmodule()无效?因为整数、字符串这类不可变基本类型,导入时是复制值而非引用模块内的对象,它们的__module__属性指向builtins,而非定义它们的模块。 - 该方法的优势:直接从源码层面分析导入关系,能准确捕获所有显式导入的模块,完全满足依赖合规检查的需求,避免了通过对象实例追溯的局限性。
内容的提问来源于stack exchange,提问作者Alberto B
相关产品推荐
相关产品推荐

