Py_Initialize失败 - 无法加载文件系统编解码器

时间:2011-04-17 16:22:38

标签: c++ python

我试图整理一个使用python 3.2的简单c ++测试项目。该项目构建正常,但Py_Initialize引发致命错误:

Fatal Python error: Py_Initialize: unable to load the file system codec
LookupError: no codec search functions registered: can't find encoding

最小代码:

#include <Python.h>

int main (int, char**)
{
  Py_Initialize ();
  Py_Finalize ();
  return 0;
}

操作系统是32位Vista。

使用的python版本是一个python 3.2调试版本,使用VC ++ 10从源代码构建。

来自同一版本的python_d.exe文件运行没有任何问题。

有人可以解释这个问题以及如何解决它吗?我自己的google-fu让我失望。

编辑1

在浏览了python源代码之后,我发现,正如错误所说,没有注册编解码器搜索功能。 codec_registerPyCodec_Register都是应有的。只是在代码中没有任何一个叫做这些函数。

我真的不知道这意味着什么,因为我仍然不知道应该调用这些函数的时间和地点。从我的其他python构建(3.1.3)的源代码中完全没有引发错误的代码。

编辑2

在下面回答了我自己的问题。

14 个答案:

答案 0 :(得分:39)

检查PYTHONPATHPYTHONHOME环境变量,确保它们不指向Python 2.x.

http://bugs.python.org/issue11288

答案 1 :(得分:27)

之前已经提到了部分内容,但简而言之,这对我的环境起作用,我有多个Python安装和我的全局操作系统环境设置指向不同的安装。遇到问题时我尝试使用的那个。

确保您的(本地或全球)环境完全设置为指向您要使用的安装,例如:你有两个(或更多)安装,比方说python27和python33(抱歉这些是windows路径,但以下内容对于等效的UNIX风格路径也应该有效,请告诉我这里我缺少的任何东西(可能DLL路径可能不同)):

C:\python27_x86

C:\python33_x64

现在,如果您打算使用python33安装,但您的全局环境指向python27,请确保您更新环境(PATHPYTHONHOME 可能是可选的(例如,如果你暂时在本地shell中工作)):

PATH="C:\python33_x64;%PATH%"

PYTHONPATH="C:\python33_x64\DLLs;C:\python33_x64\Lib;C:\python33_x64\Lib\site-packages"

PYTHONHOME=C:\python33_x64

请注意,如果开发环境需要,您可能需要/想要将任何其他库路径附加到PYTHONPATH,但要DLLsLib和{{1}正确设置是最重要的。

希望这有帮助。

答案 2 :(得分:6)

核心原因很简单:Python找不到它的模块目录,所以当然也不能加载encodings

Python doc on embedding说“Py_Initialize()根据其最佳猜测计算模块搜索路径”......“特别是,它会查找名为lib/pythonX.Y的目录”

然而,如果模块安装在(只)lib - 相对于python二进制文件 - 上面的猜测是错误的。

虽然文档说PYTHONHOMEPYTHONPATH被认为是,但我们发现事实并非如此;他们的实际存在或内容完全不相关。

唯一有效的方法是拨打Py_SetPath(),例如[path-to]\lib作为之前的参数 Py_Initialize()

当然,这只是嵌入场景的一个选项,其中一个人可以直接访问和控制代码;使用现成的解决方案,可能需要采取特殊步骤来解决问题。

答案 3 :(得分:4)

从python3k开始,启动需要编码模块,可以在PYTHONHOME \ Lib目录中找到。 实际上, API Py_Initialize()执行init并导入编码模块。 确保PYTHONHOME \ Lib在sys.path中并检查编码模块是否存在。

答案 4 :(得分:4)

我遇到了完全相同的问题(相同的Python版本,操作系统,代码等)。

你只需要在程序的工作目录中复制Python的Lib /目录(在VC上就是.vcproj所在的目录)

答案 5 :(得分:4)

尝试在Mac OS下安装brew的python3同样的事情!这里的问题是,在Mac OS中,自制软件使“真正的”python比你想象的更深。您可以从自制软件输出中想到

$ echo $PYTHONHOME
/usr/local/Cellar/python3/3.6.2/
$ echo $PYTHONPATH
/usr/local/Cellar/python3/3.6.2/bin

是正确的,但调用$ PYTHONPATH / python3立即崩溃,中止6“无法找到编码。”这是因为虽然$ PYTHONHOME看起来像一个完整的安装,有一个bin,lib等,但它不是真正的Python,它在Mac OS“框架”中。这样做:

PYTHONHOME=/usr/local/Cellar/python3/3.x.y/Frameworks/Python.framework/Versions/3.x
PYTHONPATH=$PYTHONHOME/bin

(代替版本号),它会正常工作。

答案 6 :(得分:3)

发布版本似乎出现了问题,或者未能包含相应的编解码器,或者错误地识别用于系统API的编解码器。由于python_d可执行文件正在运行,os.getfsencoding()会返回什么? (使用C API在Initialize / Finalize调用之间调用它)

答案 7 :(得分:3)

我遇到了python 3.5,anaconda 3,windows 7 32位这个问题。我通过将pythonX.lib和pythonX.dll文件移动到我的工作目录并调用

来解决它
Py_SetPythonHome(L"C:\\Path\\To\\My\\Python\\Installation");

在初始化之前,它可以找到所需的标题,我的路径是&#34; ... \ Anaconda3 \&#34;。调用Py_SetPythonHome的额外步骤对我来说是必需的,否则我最终会在python导入文件中得到其他奇怪的错误。

答案 8 :(得分:2)

因此,由于某种原因,python dll无法找到编码模块。 python.exe可执行文件显然找到它,因为它具有预期的相对路径。修改搜索路径有效。

所有这一切的原因?不知道,但至少它是有效的。我非常怀疑某个地方出现了错字,这通常是看似奇怪错误的原因。

答案 9 :(得分:2)

我遇到了问题,正在修补这里提到的不同解决方案。因为我从Visual Studio运行我的项目,显然,我需要在Visual Studio中设置环境路径而不是系统路径。

在项目解决方案\ properties \ environment中添加一个简单的PYTHONHOME = PATH \ TO \ PYTHON \ DIR解决了这个问题。

答案 10 :(得分:2)

对我而言,当我将 Python 64位 3.6.4 更新为 3.6.5 时,就发生了这种情况。它抛出了一些错误,如&#34;无法解压缩python.dll。你有权限。&#34;

Pycharm也无法加载解释器,即使我在设置中重新加载它。运行0x0000000000067A98命令会出现相同的错误,无论是否有管理员模式。

原因

安装Python时出现错误,python安装目录中的 include 文件夹 C:\ Users \ USERNAME \ AppData \ Local \ Programs \ Python \ Python36 缺失< / p>

重新安装Python也可以解决问题。(不删除和安装)

解决方案

再次卸载Python并安装Python。

因为运行安装程序只是提取相同的文件,不包括包含文件夹

答案 11 :(得分:1)

在我的情况下,对于Windows,如果你安装了多个python版本,如果PYTHONPATH指向一个版本,则其他版本不起作用。我发现如果你只删除PYTHONPATH,它们都可以正常工作

答案 12 :(得分:1)

我遇到了同样的问题,并发现了这个问题。但是从这里的答案我不能解决我的问题。我开始调试cpython代码,并认为可能会发现我的错误。因此,我在python问题跟踪器上打开了一个问题。

我的错误是我不了解Py_SetPath清除了所有推断的路径。 因此,在调用此函数时,需要设置所有路径。

为完整起见,我还复制了下面对话中最重要的部分。


我的原始问题文本

我使用Visual Studio 2017在Windows上自己编译了CPython 3.7.3的源代码以及一些软件包,例如numpy。当我启动Python解释器时,我能够导入和使用numpy。但是,当我通过C-API运行相同的脚本时,会得到一个ModuleNotFoundError

所以我要做的第一件事是检查numpy是否在我的站点软件包目录中,并且确实有一个名为numpy-1.16.2-py3.7-win-amd64.egg的文件夹。 (之所以有意义是因为python解释器可以找到numpy)

我要做的下一件事是获取有关通过C-API运行脚本时创建的sys.path变量的一些信息。

#### sys.path content ####
C:\Work\build\product\python37.zip
C:\Work\build\product\DLLs
C:\Work\build\product\lib
C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2017\PROFESSIONAL\COMMON7\IDE\EXTENSIONS\TESTPLATFORM
C:\Users\rvq\AppData\Roaming\Python\Python37\site-packages

检查sys.path的内容,我注意到两件事。

  1. C:\Work\build\product\python37.zip具有正确的路径'C:\Work\build\product\'。没有压缩文件。我所有的文件和目录都已解压缩。因此,我将文件压缩到名为python37.zip的存档中,这解决了导入错误。

  2. C:\Users\rvq\AppData\Roaming\Python\Python37\site-packages是错误的,应该是C:\Work\build\product\Lib\site-packages,但我不知道如何创建此错误路径。

接下来我要尝试的是在调用Py_SetPath(L"C:/Work/build/product/Lib/site-packages")之前使用Py_Initialize()。这导致了

  

致命的Python错误'无法加载文件系统编码'   ModuleNotFoundError:没有名为“编码”的模块

我使用这两个调用创建了一个最小的c ++项目,并开始调试Cpython。

int main()
{
  Py_SetPath(L"C:/Work/build/product/Lib/site-packages");
  Py_Initialize();
}

我跟踪了Py_Initialize()的呼叫,直到

的呼叫。
static int
zipimport_zipimporter___init___impl(ZipImporter *self, PyObject *path)

在zipimport.c内部

此函数上方的注释指出以下内容:

  

创建一个新的zipimporter实例。 “ archivepath”必须类似于路径   zipfile或zipfile中特定路径的对象。对于   例如,它可以是“ /tmp/myimport.zip”,或者   '/tmp/myimport.zip/mydirectory',如果mydirectory是有效目录   在存档中。如果“ archivepath”,则引发“ ZipImportError”   没有指向有效的Zip存档。的“存档”属性   zipimporter对象包含目标zip文件的名称。

因此,对于我来说,C-API似乎期望使用Py_SetPath设置的路径是zipfile的路径。这是预期的行为还是错误? 如果不是错误,是否有办法更改它,以便它也可以检测目录?

PS:使用Python 3.5.2+(这是我之前在项目中使用的版本)时,我没有发生ModuleNotFoundError。我还检查了是否设置了任何PYTHONHOME或PYTHONPATH环境变量,但在系统上没有看到其中之一。


答案

这可能是文档失败最多的原因。不过,我们正在重新设计初始化过程中,因此是提供此反馈的好时机。

简短的答案是,您需要确保Python可以找到Lib/encodings目录,通常是将标准库放在sys.path中。 Py_SetPath清除所有推断的路径,因此您需要指定Python应该看的所有位置。 (Python自动显示位置的规则很复杂,并且因平台而异,我很想解决这个问题。)

不存在的路径是可以的,那就是zip文件。您可以选择将stdlib放入zip文件中,如果您将其命名为默认路径,则会自动找到该文件,但也可以将其解压缩并引用目录。

完整的嵌入过程远远超过了我准备在手机上键入的内容。希望这足以让你现在走。

答案 13 :(得分:0)

对于在Visual Studio工作的人,只需将includeLiblibs目录添加到下面的Include DirectoriesLibrary DirectoriesProjects Properties -> Configuration Properties > VC++ Directories

例如,我的系统上有Anaconda3并使用Visual Studio 2015,这就是设置的样子(请注意Include和Library目录): enter image description here

编辑:

正如bossi所指出的那样,在用户PYTHONPATH部分中设置Environment Variables似乎很有必要。 样本输入可以像这样(就我而言):

C:\Users\Master\Anaconda3\Lib;C:\Users\Master\Anaconda3\libs;C:\Users\Master\Anaconda3\Lib\site-packages;C:\Users\Master\Anaconda3\DLLs

似乎是必要的。

此外,在用户环境变量中设置Visual Studio后,需要重新启动PYTHONPATH才能使更改生效。

还请注意:

确保将PYTHONHOME环境变量设置为Python 您要使用的解释器。 Visual Studio中的C ++项目依赖 此变量可找到诸如python.h之类的文件,这些文件在 创建一个Python扩展。