Ubuntu下C++嵌入Python3.11.2遇AttributeError:模块无__file__属性
我开发了一个嵌入Python3.11.2的C++程序,调用包含第三方模块及标准库模块的Python脚本时出现如下错误:
excType: 'AttributeError'
excValue: AttributeError("module 'abc' has no attribute 'file'")
excTraceback: <traceback object at 0x7f1e48c5f200>
直接运行该Python脚本一切正常,abc模块的__file__属性可正常获取。
我通过以下配置从源码编译Python3.11.2:
--enable-optimizations --enable-shared --prefix="Path/To/My/Custom/Build/Folder/"
奇怪的是,所有导入的第三方模块均有__file__属性且加载正常。我的操作系统为Ubuntu 22.04.3。
测试os等其他标准库模块时,调用函数正常,但同样无法找到__file__属性;直接运行Python则可正常获取该属性。
更新:我发现嵌入的Python前缀为空,设置PYTHONHOME无效,请问如何修改该前缀?
1. 在C++代码中直接设置Python前缀
仅通过环境变量PYTHONHOME设置前缀在嵌入场景下可能不生效,必须在初始化Python解释器前,调用Python的C API明确指定前缀路径:
#include <Python.h> int main() { // 替换为你的自定义Python编译路径(需用宽字符格式) const wchar_t* custom_python_home = L"Path/To/My/Custom/Build/Folder/"; Py_SetPythonHome(custom_python_home); // 初始化Python解释器 Py_Initialize(); // 执行你的Python脚本或逻辑 // ... // 清理解释器 Py_Finalize(); return 0; }
2. 理解问题根源
标准库模块没有__file__属性,是因为Python前缀未正确设置时,解释器无法找到标准库的源码文件,会默认加载内置的字节码版本——这类模块不会携带__file__属性。第三方模块能正常获取该属性,是因为它们的安装路径不在标准库目录,解释器能直接找到对应的文件。
设置正确前缀后,解释器会从指定路径加载标准库的源码文件,模块的__file__属性就会正常生成。
3. 编译链接注意事项
编译嵌入Python的C++程序时,必须正确关联自定义编译的Python库:
- 编译时指定头文件路径:
-IPath/To/My/Custom/Build/Folder/include/python3.11 - 链接时指定库文件路径和库名:
-LPath/To/My/Custom/Build/Folder/lib -lpython3.11 - 运行程序前,可通过环境变量指定库路径:
export LD_LIBRARY_PATH=Path/To/My/Custom/Build/Folder/lib:$LD_LIBRARY_PATH
内容的提问来源于stack exchange,提问作者roelv

