如何重写 Py_GetPrefix() 和 Py_GetPath()?

5 投票
4 回答
1798 浏览
提问于 2025-04-15 12:59

我正在尝试嵌入Python解释器,并且需要自定义Python标准库的加载方式。我们的库将从与可执行文件相同的目录加载,而不是从prefix/lib/目录加载。

我们已经成功地在调用Py_Initialize()之后手动修改sys.path来实现这一点,但这样做会产生一个警告,因为Py_Initialize在./lib/目录中寻找site.py,而在调用Py_Initialize之前这个文件并不存在,直到我们更新了sys.path。

Python的C API文档提到可以覆盖Py_GetPrefix()和Py_GetPath(),但没有说明具体该怎么做。有没有人知道我该如何去覆盖它们呢?

4 个回答

4

我看到这个问题很早就被问过了,但我刚刚遇到了同样的问题。Py_NoSiteFlag可以帮助处理网站模块,但一般来说,最好是重写一下Modules/getpath.c;Python的文档官方推荐这样做是为了“[一个]需要完全控制的应用程序”。Python在初始化时确实会导入一些模块(我遇到的问题就是encodings模块),所以,除非你不需要这些模块或者已经把它们嵌入进去了,否则模块搜索路径必须在你调用Py_Initialize()之前就准备好。

根据我的理解,Py_GetPath只是返回模块的搜索路径;Py_GetProgramFullPath这个名字就说明了它的作用;而Py_GetPrefixPy_GetExecPrefix几乎没有人使用,除了某个神秘的“ILU”。

4

你有没有想过在调用 Py_Initialize 之前,使用 putenv 来调整一下 PYTHONPATH 呢?

5

你可以把 Py_NoSiteFlag = 1 这个设置为1,然后调用 PyInitialize,再根据需要自己导入 site.py 文件。

撰写回答