SWIG %import在Python2正常运行,Python3模块导入报错求助
解决Python3下SWIG模块化项目的导入报错问题
方法1:给SWIG模块指定父包
直接在module2.i和module3.i的%module指令里加上父包参数,让SWIG自动生成符合Python3规则的导入语句:
// File module2.i %module(package="Test") module2 %{ #include "module1.h" %} %import "module1.i" %include "module2.h"
// File module3.i %module(package="Test") module3 %{ #include "module1.h" %} %import "module1.i" %include "module3.h"
这样生成的module2.py和module3.py里会自动用from Test import module1这种绝对导入,完美适配Python3的包导入逻辑。
方法2:注入相对导入代码兼容多版本
如果不想固定死父包名称,可以在.i文件末尾加一段%pythoncode,替换掉SWIG默认的导入逻辑:
// File module2.i %module module2 %{ #include "module1.h" %} %import "module1.i" %include "module2.h" %pythoncode %{ # 替换默认导入,用相对导入适配Python3,同时兼容Python2 try: from . import module1 except ImportError: import module1 %}
这段代码会被SWIG插入到生成的Python文件里,优先用相对导入,失败的话再降级到旧的导入方式,兼顾两个版本的兼容性。
方法3:批量修改生成后的Python文件(应急方案)
要是上面的SWIG内置方法用不了,那就直接改生成好的.py文件,把import module1替换成相对导入。用脚本批量改更高效:
Linux/macOS 用sed命令:
sed -i 's/import module1/from . import module1/' Test/module2.py Test/module3.py
Windows 用PowerShell:
(Get-Content Test/module2.py) -replace 'import module1', 'from . import module1' | Set-Content Test/module2.py (Get-Content Test/module3.py) -replace 'import module1', 'from . import module1' | Set-Content Test/module3.py
注意:每次重新生成SWIG代码后都要跑一遍这个脚本。
最后验证步骤
- 记得给
Test目录加个空的__init__.py文件(Python3虽然允许没有,但加了兼容性更好) - 重新生成SWIG模块代码
- 在
Test目录外面运行Python,测试导入:
from Test import module2 from Test import module3
这时候就不会再报ModuleNotFoundError了。
内容的提问来源于stack exchange,提问作者Anatoly
相关产品推荐
相关产品推荐

