为了找出这个问题,用了整天一天的时间来看Python的源码,不过还好,至少还熟悉了一下Python中这些杂乱的路径,并找到了原因。
issue11320 涉及的到就是Py_SetPath这个函数!
Manual中是这么介绍这个函数的:
void Py_SetPath(const wchar_t *)
Set the default module search path. If this function is called before Py_Initialize(), then Py_GetPath() won’t attempt to compute a default search path but uses the one provided instead. This is useful if Python is embedded by an application that has full knowledge of the location of all modules. The path components should be separated by semicolons.
此外:源码的注释中,也在建议使用这个函数:
* An embedding application can use Py_SetPath() to override all of
* these authomatic path computations.
起源
非常简单的一个程序:
#include "Python.h"
int main()
{
Py_SetPath(L"/home/debao/Download/python/lib/python3.2/;"
"/home/debao/Download/python/lib/python3.2/plat-linux2;"
"/home/debao/Download/python/lib/python3.2/lib-dynload");
Py_Initialize();
PyRun_SimpleString("print(\'Hello C/C++\')");
Py_Finalize();
return 0;
}
额,为了调试的方便,我用的Qt Creator,使用的.pro文件如下:
CONFIG -=qt
SOURCES += test.cpp
INCLUDEPATH += ../include/python3.2m
LIBS += -L../lib -lpython3.2m -lpthread -ldl -lutil
编译,运行,结果出错:
Fatal Python error: Py_Initialize: Unable to get the locale encoding
LookupError: no codec search functions registered: can't find encoding
错误出在,Py_InitalizeEx中initfsencoding(interp)一句,调试,调试,调试
最终发现Manual中说错了一句。路径中不是分号分割,而是用 冒号。准确一点,Windows下用分号,其他平台用冒号。
恩,我改
#include "Python.h"
int main()
{
Py_SetPath(L"/home/debao/Download/python/lib/python3.2/:"
"/home/debao/Download/python/lib/python3.2/plat-linux2:"
"/home/debao/Download/python/lib/python3.2/lib-dynload");
Py_Initialize();
PyRun_SimpleString("print(\'Hello C/C++\')");
Py_Finalize();
return 0;
}
这下好了,上面的错误没有了,可是,错误信息更长了....
Traceback (most recent call last):
File "/home/debao/Download/python/lib/python3.2/sysconfig.py", line 339, in _init_posix
_parse_makefile(makefile, vars)
File "/home/debao/Download/python/lib/python3.2/sysconfig.py", line 222, in _parse_makefile
with open(filename, errors="surrogateescape") as f:
IOError: [Errno 2] No such file or directory: 'lib/python3.2/config-3.2m/Makefile'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/debao/Download/python/lib/python3.2/site.py", line 529, in <module>
main()
File "/home/debao/Download/python/lib/python3.2/site.py", line 517, in main
known_paths = addusersitepackages(known_paths)
...
过程就不描述了,这个问题就是7个月前的issue11320所报告的。
原因
调用Py_SetPath会使得 sys.prefix 和 sys.exec_prefix 都为空。这点Manual中也提到了:
This also causes sys.executable to be set only to the raw program name (see Py_SetProgramName()) and for sys.prefix and sys.exec_prefix to be empty.
可是,在sysconfig.py文件中,需要使用 sys.prefix 来找到一个配置用的 makefile 文件,而空串 sys.prefix 导致生成错误的文件路径名:lib/python3.2/config-3.2m/Makefile,因此该文件无法被找到。
在Py_InitializeEx执行的后期,会导入 site.py 模块,而 site.py 模块需要 sysconfig.py 模块,从而导致这个问题。
如何解决?
不清楚这个bug如何解决,反正暂时在issue11320留下commit了,希望对官方解决这个问题能有帮助。
Py_SetPath目前是用不成了,不过还好,我们可以使用Py_SetPythonHome或者Py_SetProgramName。除此之外,环境变量也是可以用的,只是个人不太喜欢。
#include "Python.h"
int main()
{
#if 0
Py_SetPythonHome(L"/home/debao/Download/python/");
#else
Py_SetProgramName(L"/home/debao/Download/python/bin/python3");
#endif
Py_Initialize();
PyRun_SimpleString("print(\'Hello C/C++\')");
Py_Finalize();
return 0;
}
参考
分享到:
相关推荐
这就需要用到如`py_innodb_page_info`这样的工具,它为我们提供了一扇窗口,让我们可以深入到InnoDB存储引擎的底层,直观地理解日志(redo log和undo log)以及数据文件的工作方式。本文将详细介绍`py_innodb_page_...
- 加载AIGER文件:`aiger_model = py_aiger_sat.load_aiger('path_to_your_file.aig')` - 转换为SAT问题:`sat_instance = aiger_model.to_sat()` - 解决SAT问题:`solution = sat_instance.solve()` - 分析解决...
`py_polars`是一个针对Python的高性能数据处理库,它提供了类似`pandas`的数据框架,但速度更快,内存效率更高。`py_polars`是Polars库的Python绑定,Polars是用Rust语言编写的,其核心在于其强大的列式计算引擎。这...
pip install path/to/py_eodms_rapi-1.2.7-py3-none-any.whl ``` 安装完成后,即可在Python脚本中导入并使用`py_eodms_rapi`,例如: ```python from py_eodms_rapi import EODMS_RAPIClient client = EODMS_...
pip install path/to/py_cn_phone_area_code-1.0.0-py2.py3-none-any.whl ``` 安装完成后,可以导入库并调用相关函数,例如: ```python import py_cn_phone_area_code as pcpac area_code = pcpac.get_area_...
**PyPI 官网下载 | py_stac-0.2.4-py2.py3-none-any.whl** PyPI(Python Package Index)是Python开发者最常用的一个资源库,它提供了大量的Python软件包供用户下载和使用。在标题中提到的"PyPI 官网下载"是指我们...
总结起来,`py_config_parser-2.0.1-py3.7.egg`是一个针对Python 3.7的配置文件处理库,它提供了一种简单、高效的API来读写配置文件,适用于各种Python后端项目。通过理解和掌握这个库,我们可以提升在处理配置文件...
"PyPI 官网下载 | bx_py_utils-27.tar.gz"这个标题表明我们讨论的是一个从Python Package Index(PyPI)官方源下载的软件包。PyPI是Python社区广泛使用的资源库,它存储了大量的开源Python库,方便开发者下载和安装...
pip install path/to/py_hPickle-1.0.0-py3-none-any.whl ``` 安装完成后,就可以在Python代码中导入并使用`py_hPickle`库来处理数据序列化和反序列化任务了。 总结,`py_hPickle-1.0.0-py3-none-any.whl`是PyPI上...
"Python库 | py_draw-0.0.5-py3-none-any.whl" 是一个针对Python编程语言的库,名为 `py_draw` 的版本0.0.5。这个库是通过`.whl`(Wheel)格式提供的,这是一种预编译的Python软件包,旨在简化安装过程,使得用户...
pip install path/to/py_aiger_ptltl-1.1.1-py3-none-any.whl ``` 安装完成后,你可以在Python代码中导入库并使用其提供的函数来转换P-TLTL公式和创建AIGER模型。 **5. 应用场景** `py_aiger_ptltl` 库主要应用于...
通过pip工具,我们可以直接将这个.whl文件安装到Python环境中,命令通常为`pip install path/to/py_lapper-0.9.5-py3-none-any.whl`。 关于"py_lapper"库的具体功能,虽然描述中并未提供详细信息,但我们可以根据其...
path.py, "Path" 对象方便地包装各种文件/路径相关功能 许可证在项目元数据( 典型的是一个或者多个Trove分类器) 中指明了许可证。 有关更多细节,请参见这里说明。 path.pypath.py 为第一类实体实现了路径对象,允许...
标题 "PyPI 官网下载 | py_Ultroid-47.2b0-py3-none-any.whl" 指示的是一个Python包,它可以从Python Package Index(PyPI)官方网站获取。这个包名为“py_Ultroid”,版本号为47.2b0,表明这是一个测试版软件(b0...
widget_set_change.py
chess_set.py
step2.5_test_set_prediction.py
Problem_Set_1_Part_A.py
"py_manga-0.0.8-py3-none-any.whl"是一个Python库的发行文件,它为开发者提供了对特定领域或任务的特定支持。本文将深入探讨这个库的使用、安装以及可能的功能。 首先,让我们理解"py_manga"这个名字。通常,...
py_03_第一个函数.py py_04_第一个函数改造.py py_05_函数的参数.py py_06_函数的返回值.py py_07_函数的嵌套调用.py py_08_打印分隔线.py py_09_打印多条分隔线.py py_10_分隔线模块.py py_10_模块体验.py