我对“找不到与平台无关的库<prefix>”的原因的诊断正确吗,我该如何解决?

时间:2019-03-22 18:43:33

标签: python c macos

我正在尝试将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'

2 个答案:

答案 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
}