python - importlib._bootstrap 和 python 解释器初始化

标签 python python-3.x initialization cpython

CPython解释器模块导入系统是用python本身编写的,并在importlib._bootstrap中初始化。它的源代码可以在 importlib/_bootstrap.py 中看到,但它不是从那里加载的。相反,它是从所谓的卡住模块加载的,其字节码是 baked进入解释器库(python37.dll)。

解释器通过 importing _frozen_importlib (it's a name for importlib._bootstrap baked into the interpreter) 初始化自身和 calling _install function defined there, passing sys and _imp modules as arguments_install来电 _setup ,它初始化该模块所需的运行时,然后添加 2 个导入器,实现 PEP 451 .

在开发自定义导入器时,我在 _bootstrap.py 或我的导入器中遇到了几个错误,因此我需要将一些调试输出添加到 _bootstrap.py 中。

因此,我尝试让解释器从磁盘加载 _bootstrap.py,而不是从内置字节码加载。

对 cpython 源代码的分析表明,为了导入内置模块,我不需要大部分的规范类。因此可以使用 _create_builtin

导入内置模块
class UltraSimpleSpec:
    __slots__=("name",)
    def __init__(self, name):
       self.name = name

def _install(sys, _imp):
    io = _imp.create_builtin(UltraSimpleSpec("_io"))
    _bi = _imp.create_builtin(UltraSimpleSpec("builtins"))
    fd = io.open("path/to/_bootstrap.py", "rt") # exits the _install function without any exception, how can it do it?
    raise _bi.Exception("Never called") # _bi.print doesn't work, because sys.stdout is not initialized, so I have to use exceptions for debug output
    ...

不幸的是,发生了一些奇怪的事情,调用 io.open 导致 _install 退出,控制流永远不会到达下一条语句。并且似乎没有引发异常,当出现异常时,解释器会打印它,而是由于缺少 _install 的副作用而在另一个地方引发异常。

还有一个麻烦是 sys.stdout 未初始化,因此我们无法打印并且必须依赖异常来进行调试输出。

所以

  1. 我应该如何使open工作?

  2. 我应该如何初始化sys.stdout

最佳答案

不完全是一个答案,但我只为我的案例解决了一个问题(加载 python 源代码)。

How should I make open work?

结果当时字符串编码不可用,所以我用了rb而不是r。然后我将字节传递给compile,它可以处理它们。

关于python - importlib._bootstrap 和 python 解释器初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54224735/

相关文章:

尽管队列已满,Python 多处理队列 get() 超时

python - 将给定字符串限制在白名单中的最佳方法

python 3.2 : pygame. KEYDOWN 只能工作 1 次?

c++ - 崩溃删除 [ ] 初始化的 char 字符串

python - Pandas:计算列中的一些值

python插入mysql

python - 如何在 python 中读取文本文件,然后在同一个文件上写入内容

python3-config --ldflags 不包括 -lpython3.x

c++ - 初始化变量和实例化变量有什么区别?

C++ 无状态类的静态初始化