我正在尝试将python嵌入C应用程序中。目前,我正在尝试获得以下Hello World Style示例
#include <..../anaconda3/include/python3.7m/Python.h> // I've abbreviated this path for privacy
int main()
{
Py_Initialize();
PyRun_SimpleString("from time import time,ctimenprint('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",因为这篇文章中的一个答案表明它是应将其设置为Python的bin文件的父文件夹,在这种情况下,该文件是Anaconda。执行此操作并未解决问题。)。
编辑:
应用@John Bollinger建议的更改似乎部分解决了问题。结果错误现在
Fatal Python error: initfsencoding: unable to load the file system codec
ModuleNotFoundError: No module named 'encodings'
我了解上述问题,原因是我遇到此错误的原因是因为我需要给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库相同的实现)。对于 system python,在我的机器上,它将是
PYTHONHOME=/usr/lib:/usr/lib64
对于我的Anaconda 2,安装在/opt/anaconda2中,它将是
PYTHONHOME=/opt/anaconda2/lib
您不需要设置PYTHONPATH
(实际上,您可能需要确保它是 un 设置),除非您需要其他位置来搜索模块。
首先,归功于我指向这个问题(公认的非常非常非常有用的)解决方案的道路,请访问@john_bollinger。其次,我要发布此答案只是为了解决无法以正确方法解决问题的解决方案(请参阅@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
}