初始化失败-无法加载文件系统编解码器

我正在尝试整合一个使用嵌入式 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 文件运行时没有任何问题。

有人能解释一下这个问题以及如何解决它吗? 我自己的谷歌搜索失败了。

编辑1

在浏览了 python 源代码之后,我发现,正如错误所说,没有注册任何 codec 搜索函数。codec_registerPyCodec_Register都是它们应该的样子。只是这些函数在代码中都没有被调用。

我真的不知道这意味着什么,因为我仍然不知道这些函数应该在何时何地被调用。引发错误的代码在我的其他 Python 构建(3.1.3)的源代码中完全缺失。

编辑2

回答了我自己的问题。

149167 次浏览

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

Http://bugs.python.org/issue11288

发布版本中似乎出现了一些问题,要么没有包含适当的编解码器,要么错误地识别了用于系统 API 的编解码器。因为 python_d可执行文件正在工作,那么对于 os.getfsencoding()返回什么?(使用 C API 在 Initialize/Finalize 调用之间调用它)

因此,由于某种原因,pythondll 无法定位编码模块。Exe 可执行文件显然找到了它,因为它拥有预期的相对路径。修改搜索路径可以工作。

这一切的原因是什么?不知道,但至少起作用了。我高度怀疑我在某个地方打错了字,这通常是奇怪的错误的原因。

在 python3k 中,启动程序需要编码模块,可以在 PYTHONHOME Lib 目录中找到该模块。 实际上,API Py _ Initialize ()执行 init 并导入编码模块。 确保 PYTHONHOME Lib 在 sys.path 中,并检查编码模块是否存在。

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

你只需要将 Python 的 Lib/目录复制到你程序的工作目录中(在 VC 中,这个目录是。Vcproj 是)

之前已经提到过其中的一部分,但是简而言之,在我的环境中,我有多个 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,但是正确设置 DLLsLibsite-packages是最重要的。

希望这个能帮上忙。

我在 Python 3.5,蟒蛇3,Windows 732位上遇到了这个问题。我通过将 pythonx. lib 和 pythonx. dll 文件移动到工作目录中并调用

Py_SetPythonHome(L"C:\\Path\\To\\My\\Python\\Installation");

在初始化之前,以便它能够找到它需要的头,其中我的路径是“ ... ... Anaconda3”。我需要调用 Py _ SetPythonHome 这个额外的步骤,否则我会在 python 导入文件时遇到其他奇怪的错误。

在 Mac 操作系统下安装 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会立即崩溃,并且 abort 6“无法找到编码”这是因为尽管 $PYTHONHOME 看起来像是一个完整的安装,有一个 bin、 lib 等等,但它不是真正的 Python,而是在 Mac OS“ Framework”中。这样做:

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

(在适当的情况下替换版本号) ,它将工作得很好。

在我的例子中,对于 windows,如果安装了多个 python 版本,如果 PYTHONPATH指向一个版本,那么其他版本就无法工作。我发现,如果你只是删除 PYTHONPATH,他们都工作良好

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

在项目解决方案属性环境中添加一个简单的 PYTHONHOME = PATH 到 PYTHONDIR 解决了这个问题。

对我来说,这发生在我把 Python 64位3.6.4更新到 3.6.5的时候,它抛出了一些像 “无法提取 python.dll。您有权限吗?”这样的错误

Pycharm 也无法加载解释器,尽管我在设置中重新加载了它。运行 python命令会出现同样的错误,包括管理员模式和不包括管理员模式。

原因

安装 Python 时出错,Python 安装目录 C: 用户 USERNAME AppData 本地程序 Python Python 36中的 包括文件夹丢失

重新安装 Python 也无法解决这个问题

解决方案

卸载 Python 并再次安装 Python。

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

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

关于嵌入 的 Python 文档说“ Py_Initialize()根据其最佳猜测计算模块搜索路径”... ... “特别是,它查找名为 lib/pythonX.Y的目录”

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

虽然医生说 PYTHONHOMEPYTHONPATH是被重视的,但我们观察到情况并非如此; 它们的实际存在或内容完全无关紧要。

唯一有效的是对 Py_SetPath()的调用,例如 [path-to]\lib作为参数 之前 Py_Initialize()

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

我也有同样的问题,发现了这个问题。然而,从这里的答案我不能解决我的问题。我开始调试 cpython 代码,并认为我可能会被发现一个 bug。因此,我在 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的文件夹。鸡蛋。(有道理,因为 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_Initialize()之前使用 Py_SetPath(L"C:/Work/build/product/Lib/site-packages")

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

我使用这两个调用创建了一个最小的 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 的内部

上述职能的评论说明如下:

创建一个新的 zipinporter 实例 对象转换为 zipfile 或 zipfile 内部的特定路径 例如,它可以是“/tmp/myimport. zip”,或者 “/tmp/myimport. zip/mydirectory”,如果 mydirectory 是有效目录 如果‘ archive epath’,则会引发‘ ZipImport Error’ 不指向有效的 Zip 归档文件 对象包含目标 zipfile 的名称。

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

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


回答我

这可能是文档失败,而不是其他原因。不过,我们正在重新设计初始化,所以现在是提供这种反馈的好时机。

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

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

一个完整的嵌入过程已经超出了我在手机上打字的能力范围。希望这些足够让你现在开始行动。

对于那些在 Visual Studio中工作的人,只需将 includeLiblibs目录添加到 Include DirectoriesLibrary Directories下 返回文章页面

例如,我有 Anaconda3在我的系统和工作与 Visual Studio 2015这是如何设置看起来像(注意包含和库目录) : enter image description here

编辑:

正如 Bossi所指出的那样,在用户 Environment Variables部分中设置 PYTHONPATH似乎是必要的。 样例输入可以是这样的(在我的例子中) :

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

似乎是必要的。

此外,在用户 Environment Variables 中设置了 PYTHONPATH之后,您需要重新启动 Visual Studio,以使更改生效。

还要注意:

确保将 PYTHONHOME环境变量设置为 Python Visual Studio 中的 C + + 项目依赖于 此变量用于定位诸如 python.h之类的文件,这些文件在以下情况下使用 创建一个 Python 扩展。