Python 3.5解释器需要哪些标准库模块?

8
这是一个尝试使用空的 sys.path 初始化解析器的 CPython 程序:
#include <Python.h>

int main(int argc, char** argv)
{
    wchar_t* program = NULL;
    wchar_t* sys_path = NULL;

    Py_NoSiteFlag = 1;

    program = Py_DecodeLocale(argv[0], NULL);
    Py_SetProgramName(program);

    sys_path = Py_DecodeLocale("", NULL);
    Py_SetPath(sys_path);

    Py_Initialize();

    PyMem_RawFree(program);    
    PyMem_RawFree(sys_path);
    Py_Finalize();
}

执行上述程序会产生以下错误:
Fatal Python error: Py_Initialize: Unable to get the locale encoding
ImportError: No module named 'encodings'

Current thread 0x00007ffff7fc6700 (most recent call first):
Signal: SIGABRT (Aborted)

除了encodings包之外,哪些Python 3.5标准库中的包和模块是运行Python 3.5解释器绝对需要的?我认为文档中缺少这些信息。


你可以通过运行解释器,然后查看导入模块的字典来测试它包含了什么。 - Charles Duffy
3个回答

7
以下是启动解释器时使用的软件包/模块(如@Charles Duffy在评论中指出,通过查看sys.modules)。
结果取决于是否启用了site(您的Py_NoSiteFlag = 1;意味着这不是情况,但无论如何,我都会给出两个选项:-))。
当您像_sitebuiltins和stat这样使用site时,它会带上一些其他模块,总共只能使用以下内容运行Python:
abc.py               encodings       os.py         _sitebuiltins.py  sysconfig.py
codecs.py            genericpath.py  posixpath.py  site.py           _collections_abc.py  
io.py                stat.py         _weakrefset.py

禁用site后,您将仅保留以下6个功能:

abc.py  codecs.py  encodings  io.py  os.py  _weakrefset.py

假设你是通过CPy_Initialize()来调用的(或者根据你的评论可能是在Windows上),我猜os.py实际上可能是不需要的。


“Build”是什么意思?我能够在sys.path中只使用encodings包以及_weakrefsetabccodecsio模块来运行解释器。 - bzrr
它对那些东西能做的事情不多,但仍然有一些。 - bzrr
啊,我以为你是指整个过程(即获取CPython源代码,构建它,然后还要运行它)。是的,仅需运行解释器,您需要我列出的模块/包的一个小子集。既然您已经找到了所需的模块,我想您已经回答了自己的问题 :-) @Jovito - Dimitris Fasarakis Hilliard
也许最好删除有关构建Python解释器的部分,因为这不是问题的重点,或者至少将有关实际运行它的部分移到您的答案顶部 :) - bzrr
@Jovito 我会把它删除,还有另一个问题问到了这个,我会在那里发布答案 :-) 。顺便说一下,你不需要 os.py 来执行它吗? - Dimitris Fasarakis Hilliard
1
不在Windows上。 - bzrr

1
如果按照Charles Duffy在评论中建议的方式运行解释器,您将加载像readline这样的包。虽然我已经十年没有这样做过了,但我记得如果您将Python作为C程序的扩展使用,则不需要该模块,因为没有命令行交互。其他模块可能也是如此。确定实际所需内容最快捷的方法是将所有lib/python3.5放在程序可以找到的位置,并在程序中打印sys.modules,这将为您提供一个列表,其中列出了您的程序实际加载的内容,而不是解释器启动时可能需要的内容。之后,请删除不在该列表中的所有内容。

1

这里有另一种方法 - 询问Python解释器加载了哪些模块:

$ python3.5 -v -S -c '' |& grep SourceFileLoader | sort 
import 'abc' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d12e860>
import '_bootlocale' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d1367b8>
import 'codecs' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d187fd0>
import 'encodings.aliases' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d11eac8>
import 'encodings' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d187be0>
import 'encodings.latin_1' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d12e3c8>
import 'encodings.utf_8' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d12c898>
import 'io' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d12e5f8>
import '_weakrefset' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d135080>

_bootlocale 不是必需的,但建议使用。它用于初始化 sys.stdin/sys.stdout/sys.stderr 的最佳编码。参见 https://hg.python.org/cpython/rev/fbbf8b160e8d

sys.modules 可以欺骗,因为它是可变的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接