运行时错误:丢失 sys.stdout

MSe*_*ert 2 python cpython python-3.x python-internals

我试图与调试的问题abc.ABCMeta-特别是子类的支票,并没有按预期方式工作,我想通过简单地添加一个启动print__subclasscheck__方法(我知道有调试代码更好的方法,但假装的缘故这个问题别无选择)。但是,在 Python 崩溃之后启动 Python 时(如分段错误)我收到此异常:

Fatal Python error: Py_Initialize: can't initialize sys standard streams
Traceback (most recent call last):
  File "C:\...\lib\io.py", line 84, in <module>
  File "C:\...\lib\abc.py", line 158, in register
  File "C:\...\lib\abc.py", line 196, in __subclasscheck__
RuntimeError: lost sys.stdout
Run Code Online (Sandbox Code Playgroud)

所以把它放在那里显然不是一个好主意print。但异常究竟从何而来?我只更改了 Python 代码,应该不会崩溃吧?

有人知道这个异常来自哪里以及我是否/如何避免它但仍然printabc.ABCMeta.__subclasscheck__方法中放入一个?

我使用的是 Windows 10、Python-3.5(以防万一它可能很重要)。

Jim*_*ard 6

此异常源于 CPython导入io的事实,并且间接地abc.py标准流初始化期间:

if (!(iomod = PyImport_ImportModule("io"))) {
    goto error;
}
Run Code Online (Sandbox Code Playgroud)

io导入abc模块并注册FileIO为 的虚拟子类RawIOBase,还有一些其他类 forBufferedIOBase和其他类for TextIOBase。过程中ABCMeta.register调用 __subclasscheck__

如您所知,print设置__subclasscheck__时使用in是一个很大的禁忌;初始化失败,你得到你的错误:sys.stdout

if (initstdio() < 0)
    Py_FatalError(
        "Py_NewInterpreter: can't initialize sys standard streams");
Run Code Online (Sandbox Code Playgroud)

您可以通过使用 , 保护它来绕过它hasattr(sys, 'stdout'),此时sys已初始化,而尚未初始化stdout(因此,sys在早期初始化阶段不存在):

if hasattr(sys, 'stdout'):
    print("Debug")
Run Code Online (Sandbox Code Playgroud)

现在启动 Python 时,您应该获得大量输出。