Linux下Python3.9导入math模块报PyFloat_Type未定义符号错误求助
Linux系统中使用自行安装的Python 3.9,安装结构如下:
/tools/python/bin - 包含python可执行文件 /tools/python/lib/libpython3.9.so /tools/python/lib/python3.9/lib-dynload/*
将第三方库x.so链接到libpython.so后,运行/share/python/test.py脚本时出现导入错误。
test.py脚本内容:
import unittest import math class Test_2(unittest.TestCase): def test_distance(self): self.assertAlmostEqual(box1.distance(box2), math.sqrt(2)) def suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(Test_2)) return suite
错误日志:
ImportError: Failed to import test module: test Traceback (most recent call last): File "/share/python/test.py", line 3, in <module> import math ImportError: /tools/python/lib/python3.9/lib-dynload/math.so: undefined symbol: PyFloat_Type
已做的配置:
- 设置
PYTHONPATH=/share/python - 设置
PYTHONHOME=/tools/python LD_LIBRARY_PATH中添加了/tools/python/lib路径
相关系统输出:
[abc@xyz01 ~]$ ldd /tools/python/bin/python linux-vdso.so.1 (0x00007ffc281ce000) libpython3.9.so.1.0 => /tools/python/lib/libpython3.9.so.1.0 (0x00007f28887d8000) libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f28885af000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f288838f000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f288818b000) libutil.so.1 => /lib64/libutil.so.1 (0x00007f2887f87000) libm.so.6 => /lib64/libm.so.6 (0x00007f2887c05000) libc.so.6 => /lib64/libc.so.6 (0x00007f2887840000) /lib64/ld-linux-x86-64.so.2 (0x00007f2888b6a000) [abc@xyz01 ~]$ echo $PYTHONPATH /share/python [abc@xyz01 ~]$ echo $PYTHONHOME /tools/python [abc@xyz01 bin]$ echo $LD_LIBRARY_PATH tools/python/lib:/build/tools/libstdc+/lib64:/build/tools/lib/64bit:/build/tools/lib:/build81/tools/Qt/v5/64bit/lib:/build/tools/boost/lib/64bit/:/usr/lib64:/build/tools/lib/64bit/RHEL/RHEL8:/build/tools/lib/64bit/RHEL/RHEL7:/build81/tools/libstdc++/lib64:/build81/tools/lib/64bit:/usr/X11R6/lib:/lib:/usr/lib
这个错误核心是math.so找不到Python核心库中的PyFloat_Type符号,通常由Python动态库链接方式、符号导出问题或环境变量配置错误导致,以下是具体解决步骤:
1. 检查libpython3.9.so的符号导出情况
运行命令确认PyFloat_Type是否在核心库中导出:
nm -D /tools/python/lib/libpython3.9.so | grep PyFloat_Type
- 若输出包含
PyFloat_Type(标记通常为D或T),说明符号存在; - 若无输出,说明Python编译时未导出该符号,需重新编译Python,确保禁用
-fvisibility=hidden这类隐藏符号的编译参数。
2. 修复LD_LIBRARY_PATH的路径问题
从输出可见,LD_LIBRARY_PATH中的tools/python/lib是相对路径,需改为绝对路径/tools/python/lib,否则系统无法定位到正确的库文件。临时修复执行:
export LD_LIBRARY_PATH="/tools/python/lib:$LD_LIBRARY_PATH"
若需永久生效,将该命令添加到用户~/.bashrc或系统/etc/profile文件中。
3. 检查x.so的链接依赖
确认x.so是否链接到正确的Python库:
ldd /path/to/x.so
确保它依赖的是/tools/python/lib/libpython3.9.so.1.0而非系统自带Python库。若链接错误,重新编译x.so并指定正确的头文件和库路径:
gcc -shared -fPIC -I/tools/python/include/python3.9 -L/tools/python/lib -lpython3.9 x.c -o x.so
4. 验证Python环境变量的正确性
运行命令查看Python的模块搜索路径:
/tools/python/bin/python -c "import sys; print(sys.path)"
确认/tools/python/lib/python3.9和/tools/python/lib/python3.9/lib-dynload在路径列表中。若不在,说明PYTHONHOME设置错误或Python编译时前缀路径配置有误,需调整环境变量或重新编译Python。
5. 直接测试Python解释器
先跳过脚本,直接启动Python解释器尝试导入math模块:
/tools/python/bin/python -c "import math; print(math.sqrt(2))"
- 若命令成功,问题出在脚本运行方式或
x.so加载逻辑上; - 若同样报错,说明Python本身安装存在问题,需重新编译安装,确保编译时启用
--enable-shared选项。
内容的提问来源于stack exchange,提问作者user2695082

