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

2025-02-27 09:07:00
admin
原创
59
摘要:问题描述:我正在尝试组合一个使用嵌入式 Python 3.2 解释器的简单 C++ 测试项目。该项目构建良好,但 Py_Initialize 引发致命错误:Fatal Python error: Py_Initialize: unable to load the file system codec Looku...

问题描述:

我正在尝试组合一个使用嵌入式 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

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


解决方案 1:

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

http://bugs.python.org/issue11288

解决方案 2:

之前已经提到过其中的部分内容,但简而言之,这对我的环境有效,在该环境中,我安装了多个 Python,并且我的全局操作系统环境设置为指向与遇到问题时尝试使用的安装不同的安装。

确保您的(本地或全局)环境已完全设置以指向您要使用的安装,例如您有两个(或更多)安装,比如说 python27 和 python33(抱歉,这些是 Windows 路径,但以下内容对于等效的 UNIX 样式路径也应该有效,请让我知道我在这里遗漏的任何东西(可能是 DLL 路径可能不同)):

C:python27_x86

C:python33_x64

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

PATH="C:python33_x64;%PATH%"

PYTHONPATH="C:python33_x64DLLs;C:python33_x64Lib;C:python33_x64Libsite-packages"

PYTHONHOME=C:python33_x64

PYTHONPATH请注意,如果您的开发环境需要,您可能需要/想要将任何其他库路径附加到您的,但拥有您的DLLsLibsite-packages正确设置是至关重要的。

希望这有帮助。

解决方案 3:

核心原因很简单:Python 找不到其模块目录,因此当然也无法encodings加载

Python 文档中关于嵌入的内容称“Py_Initialize()根据最佳猜测计算模块搜索路径”...“具体来说,它会查找名为lib/pythonX.Y”的目录

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

尽管文档说明了这一点PYTHONHOMEPYTHONPATH予以重视,但我们观察到事实并非如此;它们的实际存在或内容完全无关紧要。

唯一有效果的是之前Py_SetPath()使用 eg[path-to]lib作为参数的调用。 Py_Initialize()

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

解决方案 4:

在 Mac OS 下尝试安装 brew 的 python3 时遇到了同样的问题!这里的问题是,在 Mac OS 中,homebrew 将“真正的”python 放在比您想象的更深的一层。您可能会从 homebrew 输出中认为

$ 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“框架”中。请执行以下操作:

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

(适当替换版本号)它就能正常工作。

解决方案 5:

从 python3k 开始,启动需要 encodings 模块,该模块位于 PYTHONHOME\Lib 目录中。实际上,API Py_Initialize()执行初始化并导入 encodings 模块。确保 PYTHONHOME\Lib 位于 sys.path 中,并检查 encodings 模块是否存在。

解决方案 6:

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

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

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

解决方案 7:

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

您只需将 Python 的 Lib/ 目录复制到程序的工作目录中(在 VC 上,它是 .vcproj 所在的目录)

解决方案 8:

发布版本似乎出了点问题,要么未能包含适当的编解码器,要么错误地识别了用于系统 API 的编解码器。既然python_d可执行文件正在运行,那么它返回什么呢os.getfsencoding()?(使用 C API 在 Initialize/Finalize 调用之间调用它)

解决方案 9:

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

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

  • 问题对话链接

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


我原来的问题文本

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

因此,我做的第一件事是检查 numpy 是否在我的 site-packages 目录中,确实有一个名为 numpy-1.16.2-py3.7-win-amd64.egg 的文件夹。(这很合理,因为 python 解释器可以找到 numpy)

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

#### sys.path content ####
C:Workuildproductpython37.zip
C:WorkuildproductDLLs
C:Workuildproductlib
C:PROGRAM FILES (X86)MICROSOFT VISUAL STUDIO7PROFESSIONALCOMMON7IDEEXTENSIONSTESTPLATFORM
C:Users
vqAppDataRoamingPythonPython37site-packages

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

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

  2. `C:Users
    vqAppDataRoamingPythonPython37site-packages是错误的,应该是这样C:WorkuildproductLibsite-packages`,但我不知道这个错误的路径是如何产生的。

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

致命的 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.c 内部

该函数上方的注释说明如下:

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

因此,对我来说,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 中,如果您将其命名为默认路径,它将自动找到,但您也可以将其解压并引用目录。

关于嵌入的完整介绍比我准备在手机上输入的内容要多。希望这足以让你现在开始。

解决方案 10:

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

在项目解决方案\属性\环境中添加一个简单的 PYTHONHOME = PATH \ TO \ PYTHON \ DIR 解决了该问题。

解决方案 11:

当我将Python 64 位3.6.4更新到3.6.5 时,发生了这种情况。它抛出了一些错误,例如“无法提取 python.dll。您有权限吗?”

Pycharm 也无法加载解释器,尽管我在设置中重新加载了它。运行python命令时出现同样的错误,无论是否使用管理员模式。

原因

Python 安装出错,缺少Python 安装目录C:\Users\USERNAME\AppData\Local\Programs\Python\Python36中的包含文件夹

重新安装 Python 也无法解决问题。(不是删除和安装)

解决方案

卸载 Python 并重新安装 Python。

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

解决方案 12:

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

解决方案 13:

对于那些在 中工作的人来说,只需将和目录Visual Studio添加到和下
即可:include`LiblibsInclude DirectoriesLibrary DirectoriesProjects Properties -> Configuration Properties > VC++ Directories`

例如,Anaconda3在我的系统上,我Visual Studio 2015的设置如下(请注意“包含”和“库”目录):
在此处输入图片描述

编辑:

正如bossi所指出的,PYTHONPATH在用户部分进行设置Environment Variables似乎是必要的。示例输入可以是这样的(在我的情况下):

C:UsersMasterAnaconda3Lib;C:UsersMasterAnaconda3libs;C:UsersMasterAnaconda3Libsite-packages;C:UsersMasterAnaconda3DLLs

看来是必要的。

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

另请注意:

确保PYTHONHOME环境变量设置为要使用的 Python 解释器。Visual Studio 中的 C++ 项目依赖此变量来定位python.h创建 Python 扩展时使用的文件(例如)。

解决方案 14:

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

这一切的原因是什么?不知道,但至少它能正常工作。我高度怀疑是我打错了什么地方,这似乎是导致奇怪错误的原因。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2974  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1836  
  PLM(产品生命周期管理)系统在企业的产品研发、生产与管理过程中扮演着至关重要的角色。然而,在实际运行中,资源冲突是经常会遇到的难题。资源冲突可能导致项目进度延迟、成本增加以及产品质量下降等一系列问题,严重影响企业的效益与竞争力。因此,如何有效应对PLM系统中的资源冲突,成为众多企业关注的焦点。接下来,我们将详细探讨5...
plm项目管理系统   47  
  敏捷项目管理与产品生命周期管理(PLM)的融合,正成为企业在复杂多变的市场环境中提升研发效率、增强竞争力的关键举措。随着技术的飞速发展和市场需求的快速更迭,传统的研发流程面临着诸多挑战,而将敏捷项目管理理念融入PLM,有望在2025年实现研发流程的深度优化,为企业创造更大的价值。理解敏捷项目管理与PLM的核心概念敏捷项...
plm项目   47  
  模块化设计在现代产品开发中扮演着至关重要的角色,它能够提升产品开发效率、降低成本、增强产品的可维护性与可扩展性。而产品生命周期管理(PLM)系统作为整合产品全生命周期信息的关键平台,对模块化设计有着强大的支持能力。随着技术的不断发展,到 2025 年,PLM 系统在支持模块化设计方面将有一系列令人瞩目的技术实践。数字化...
plm软件   48  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用