pythonimport不到so库的可能原因
gen
在import⼀个so库⾥的类或函数时,有时发现so⽂件分明就在那路径下,可是总是报错ModuleNotFoundError: No module named ***,这种错误的可能原因有:
1.⾸先要确保so所在的路径已经包含在sys.path⾥了,如果so所在⽬录已经是在python默认的系统路径⾥,例
如/usr/lib/python3.6/dist-packages/或者/usr/local/lib/python3.6/dist-packages/之下的任何层级的⽬录,不⽤做任何设置,如果是其他路径,可以通过设置PYTHONPATH或者程序⾥使⽤sys.path.insert()或sys.path.append()把路径添加到sys.path⾥来。
2.路径包含正确了,检查so库的命名的前缀和import是否不⼀致,这种so库的命名是有⼀定规则的,例如,Linux上⼀般是
<so_name>.cpython-<python-version>-<cpu-platform>-linux-gnu.so,在import时指定的名字需要和<so_name>保持⼀致。
3.命名正确了,检查后⾯的后缀cpython-<python-version>-<cpu-platform>-linux-gnu.so是否在你当前使⽤的python版本的⽀持范围内,例如,你的so库是python3的,可你在误操作下在使⽤python2运⾏程序,或者你的so库是针对python3.5的(so后缀⾥的python-version=35m),但你当前使⽤的是python3.6,也不⾏,所以如果不是在只安装了⼀种版本的python的环境⾥,运⾏python程序前,最好检查⼀下python版本是否是你所希望的,这个是在安装了多个版本的python的环境下或者升级了python版本后经常不经意下易犯的错误,有时还被坑浪费很多时间查原因,除了so库分明在那⾥却总是报ModuleNotFoundError,还有其他七七⼋⼋奇怪的错误,查原因最后发现是python版本⽤错了,⽓得⾎冲脑门。
怎么确认你当前使⽤的python版本⽀持哪些后缀的库能被import呢,很简单,执⾏下⾯的代码:
import importlib.machinery
print(importlib.machinery.all_suffixes())
Windows下输出的⽰例:
Linux下输出的⽰例:
arm64 arch:
x86_64 arch:
4.路径存在冲突,so分明在某个已包含的⽬录下存在,没有其他的错误,可还总是报错ModuleNotFoundError,这种情况也是很坑⼈的,花费了很久时间想不出原因来,就是没想到可能路径上存在重名的冲突,例如,我第⼀次使⽤python代码调⽤mediapipe时出现报错ModuleNotFoundError: No module named 'mediapipe.python._framework_bindings',其他什么错误原因都没发现,郁闷地熬夜,最后发现虽然/usr/local/lib/python3.6/site-packages/mediapipe/python/_framework_bindings.cpython-36m-x86_64-linux-gnu.so是存在的,但是在运⾏程序的⼯作⽬录下也有个使⽤过⽤来build出meaidpipe的wheel包的源码⽬录,由于当前⼯作⽬录加⼊了sys.path⾥最前⾯,于是python搜索路径时⾃然是优先的/workspace/mediapipe/python/...,这个下⾯确实是没有那个so⽂件,于是把这⾥的mediapipe⽬录改名或者移⾛,问题就消失了。
5.最后,如果是⾃⼰实现的so库,要想能被python import,so库的内部实现按规范来。
python默认安装路径例如,使⽤g++编译代码的话要必须使⽤extern "C"限制编译⽣成的名字不会被改变,对要import的函数需要以对应的initxxx()来命名(使⽤g++编译时会把函数名字增加前后缀导致函数名被改变,编译出来的so被python import 时,会报类似下⾯的错误
ImportError: dynamic module does not define init function (initmyModule)
from myModule import *
#include <Python.h>
/*
* Function to be called from Python
*/
static PyObject* py_myFunction(PyObject* self, PyObject* args)
{
char *s = "Hello from C!";
return Py_BuildValue("s", s);
}
/*
* Another function to be called from Python
*/
static PyObject* py_myOtherFunction(PyObject* self, PyObject* args) {
double x, y;
PyArg_ParseTuple(args, "dd", &x, &y);
return Py_BuildValue("d", x*y);
}
static PyMethodDef myModule_methods[] = {
{"myFunction", py_myFunction, METH_VARARGS},
{"myOtherFunction", py_myOtherFunction, METH_VARARGS},
{NULL, NULL}
};
extern "C" void void initmyModule()
{
(void) Py_InitModule("myModule", myModule_methods);
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论