我正在尝试将python嵌入到C应用程序中。目前,我正在尝试使以下hello世界风格示例正常工作
#include <..../anaconda3/include/python3.7m/Python.h> // I've abbreviated this path for privacy
int main()
{
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\nprint('Today is', ctime(time()))\n");
Py_FinalizeEx();
return(EXIT_SUCCESS);
}
我已经可以编译此示例,但是运行它时出现以下错误
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
Fatal Python error: initfsencoding: unable to load the file system codec
ModuleNotFoundError: No module named 'encodings'
我安装了多个版本的python(python3,我使用的是macOS),并且想要运行我已安装的特定anaconda版本。据我了解上述问题,得到此错误的原因是因为我需要为python查找库/模块提供特定的路径。设置PYTHONHOME和/或PYTHONPATH应该可以解决此问题。但是,我不确定该将该值设置为什么。
我的问题有两个。 (1)我是否正确诊断了问题? (2)如果是这样,我应该将这两个环境变量设置为什么?具体来说,有哪些具体路径?尽管还有其他几篇有关此问题的文章,但似乎都没有给出应该提供的路径(我尝试将PYTHONHOME变量设置为“ .... / anaconda”,因为this中的答案之一post指出应将其设置为python bin文件的父文件夹,在本例中为anaconda。这样做不能解决问题。)
编辑:
应用@John Bollinger建议的更改似乎可以部分解决问题。现在产生的错误是
Fatal Python error: initfsencoding: unable to load the file system codec
ModuleNotFoundError: No module named 'encodings'
答案 0 :(得分:1)
据我了解上述问题,我收到此错误的原因 是因为我需要为python查找提供特定的路径 库/模块。设置PYTHONHOME和/或PYTHONPATH应该可以修复 那么这个问题。
[...]
我正确诊断了问题吗?
听起来像这样。 Python解释器根据PYTHONHOME
或其安装位置和编译时配置选择默认的模块路径,但是当您将解释器嵌入另一个程序时,后者不在窗口之内。解释器使用PYTHONPATH
来标识其他目录以搜索模块。
使用独立解释器时,通常不应该设置PYTHONHOME
,但是在嵌入解释器时这样做是合理的。
如果是这样,我应该将这两个环境变量设置为什么?
我系统上python3 -h
的输出包括:
PYTHONPATH : ':'-separated list of directories prefixed to the default module search path. The result is sys.path. PYTHONHOME : alternate <prefix> directory (or <prefix>:<exec_prefix>). The default module search path uses <prefix>/pythonX.X.
尤其要注意有关Python期望在PYTHONHOME
命名的目录中找到的内容的提示。
在您的情况下,您可能应该设置PYTHONHOME
,因为解释器无法识别如何查找系统模块。变量应采用的实际值取决于所需的Python实现所处的位置(这可能应该是与您的程序链接的python库相同的实现)。对于系统 Python,在我的计算机上,它将是
PYTHONHOME=/usr/lib:/usr/lib64
对于安装在/ opt / anaconda2中的Anaconda 2,应该是
PYTHONHOME=/opt/anaconda2/lib
除非您希望Python在其他位置搜索模块,否则您无需设置PYTHONPATH
(实际上,您可能希望确保设置为 un )。
答案 1 :(得分:0)
首先,值得赞扬的是@John_Bollinger,他向我指出了这个问题的解决方案(公认的非常非常hacky)。其次,我发布此答案仅是作为无法以正确方式解决问题的人的解决方案(请参阅@John_Bollinger答案)。
我的机器上有多个python版本,所有版本都本地安装在我的配置文件中。定义“ PYTHONHOME”时,是在“ .bash_profile”中进行的。我使用IDE来开发带有嵌入式python代码的C应用程序。当我运行应用程序时,我会得到上面的错误。第一个问题是用于启动python解释器的函数“ Py_Initialize()”使用存储在PYTHONHOME中的路径来查找要启动的解释器的位置。由于我仅通过.bash_profile本地定义了PYTHONHOME,所以发生的情况是“ Py_Initialize()”未正确初始化。
第二个问题与口译员查找模块有关。解决上述问题后,解释器无法找到运行它所需的基本核心模块。我仍然不知道为什么(尽管我怀疑这与第一个问题有关)。我的解决方案是手动指定要使用的模块的路径。要获取这些信息,请运行python解释器并记录以下代码的输出:
import sys
print(sys.path)
将从此处输出的每个路径放入C代码中路径的一部分。完整的解决方案便是
#include <..../anaconda3/include/python3.7m/Python.h>
int main(int argc, char **argv, char **envp)
{
putenv("PYTHONHOME=<path to python interpreter>"); // location of interpreter. In my case ..../anaconda3/bin/python3.7m
Py_SetPath(L"<paths to python modules>"); // output from print(sys.path) above in normal path format; i.e. path1:path2:...
Py_Initialize();
// do your stuff
Py_FinalizeEx(); // close the interpreter and free the memory its using
}