Python嵌入式:PyImport_Import不从当前目录导入

7

使用下一行

pModule = PyImport_Import(pName);

仅从当前目录加载模块。

但我想从其他地方加载,有没有更好的方法?

PyRun_SimpleString("import sys\nsys.path.append('<dir>')"); 可以运行,但有点丑陋 - 我正在寻找更好的方法

谢谢!


2
Python路径中真的有<dir>吗?据我所知,PyImport_Import(<module-name>)应该与Python的import <module-name>相同。如果它不在Python路径中,那么为什么你期望它能工作呢?当然,你可以使用sysModule = PyImport_Import("sys"),然后使用PyObject_GetAttr访问sys.path,并在其上调用PyList_Append,但似乎甚至比使用PyRun_SimpleString更麻烦(虽然它应该具有更少的开销,因为它不必编译和解释代码)。 - Bakuriu
@Bakuriu - 我刚刚找到了答案 - 如下 - Guy L
2个回答

16

我在http://realmike.org/blog/2012/07/08/embedding-python-tutorial-part-1/找到了我寻找的答案。

通常,当导入模块时,Python会尝试在导入模块旁边找到模块文件(包含导入语句的模块)。然后Python尝试查找“sys.path”中的目录。通常情况下,当前工作目录不会被考虑。在我们的情况下,由于是通过API执行导入,因此不存在包含“shout_filter.py”的导入模块,Python无法从其中搜索该文件。插件也不在“sys.path”上。使Python能够找到插件的一种方法是通过API执行等效于“sys.path.append('.')”添加当前工作目录到模块搜索路径。

Py_Initialize();
PyObject* sysPath = PySys_GetObject((char*)"path");
PyObject* programName = PyString_FromString(SplitFilename(argv[1]).c_str());
PyList_Append(sysPath, programName);
Py_DECREF(programName);

SplitFilename 是我编写的一个函数,用于获取目录。


1
PyString_FromString在Python3中已被PyUnicode_FromString所取代。请参考下面的链接获取更多详细信息:https://dev59.com/cVUM5IYBdhLWcg3wc_yc - mathew gunther

-1

有一个好方法,因为这通常是使用site-packages的方式。

import sys
sys.path.append(directory) # sys.path is a list of all directories to import from

或者你可以使用

os.cwd(directory) # change the working directory

在导入之前。

另一种方法很丑陋:

import types, sys
m = types.ModuleType('module')
sys.modules['module'] = m
exec open('file').read() in m.__dict__ # python3

也许你想要一个C函数来完成你的工作,但我不知道有这样的函数。


你的意思是 PyRun_SimpleString("import sys\nsys.path.append('<dir>')"); 可以工作,但有点丑陋 - 我正在寻找更好的方法。 - Guy L
谢谢您指出这个问题。我现在已经阅读了这个问题。我只是无法正确地分类“丑陋”。请将此视为负面示例,以便您不会得到任何其他类似的答案。 - User

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接