Google Colab用importlib导入模块报'str' object has no attribute 'exec_module'求助
问题排查与修复方案
错误根因
报错AttributeError: 'str' object has no attribute 'exec_module'的核心原因是API参数传参错误:importlib.util.spec_from_loader的第二个参数要求传入符合importlib Loader协议的实例对象,你调用load_module时第一个参数传入的是拼接了前缀的Python代码字符串,导致生成的spec.loader直接被赋值为这个字符串,调用exec_module方法自然触发属性不存在的报错。
错误用法梳理
你的代码里存在以下几处逻辑问题:
load_module函数第一个参数命名为file_name,但实际调用时传入的是代码字符串,参数定义和使用逻辑完全不符- 错误使用
spec_from_loaderAPI,未传入正确的Loader实例 - 自定义的
get_file函数直接返回open的文件对象,没有自动关闭逻辑,会出现资源泄漏
修复方案
场景1:需要拼接自定义代码前缀再加载
如果你确实需要给test.py的代码添加from lib import *的前缀再导入为模块,使用以下修正代码:
import importlib.util import sys def load_module_from_code(code_str, module_name): # 创建空模块对象 module = importlib.util.module_from_spec( importlib.util.spec_from_loader(module_name, None) ) # 执行代码到模块命名空间 exec(code_str, module.__dict__) # 注册到全局模块表,避免重复加载 sys.modules[module_name] = module return module
调用方式:
# 用with上下文管理器自动关闭文件 with open('/content/gdrive/MyDrive/test/test.py', 'r', encoding='utf-8') as f: full_code = "from lib import *\n" + f.read() module = load_module_from_code(full_code, 'crawl')
场景2:无需拼接代码,直接加载本地py文件
如果不需要额外添加代码前缀,直接加载本地test.py文件可以用更规范的spec_from_file_locationAPI实现:
import importlib.util import sys def load_module_from_file(file_path, module_name): spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) sys.modules[module_name] = module spec.loader.exec_module(module) return module
调用方式:
module = load_module_from_file('/content/gdrive/MyDrive/test/test.py', 'crawl')
注意事项
- 拼接代码时注意缩进对齐,避免前缀和test.py原有代码组合后出现语法错误
- 自定义模块名不要和Python内置模块、已安装的第三方模块重名,避免命名冲突
- 读取文件优先使用with上下文管理器,不需要手动处理文件关闭逻辑
内容的提问来源于stack exchange,提问作者Calvin Creater
相关产品推荐
相关产品推荐

