运行时错误: 丢失了sys.stdout

3

我试图调试一个与abc.ABCMeta有关的问题,特别是一个子类检查没有按预期工作的问题,我想首先简单地在__subclasscheck__方法中添加一个print(我知道有更好的调试代码的方法,但为了这个问题,假装没有其他选择)。然而,当启动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

可能在那里放置print并不是一个好主意。但是,这个异常究竟来自哪里呢?我只是改变了Python代码,这不应该崩溃,对吧?

有人知道这个异常来自哪里,以及我是否/如何可以避免它,但仍然在abc.ABCMeta.__subclasscheck__方法中放置print吗?

我正在使用Windows 10、Python-3.5(以防万一这很重要)。

1个回答

7
这个异常的起因在于CPython 导入了 io,并且在标准流的初始化过程中间接地导入了abc.py
if (!(iomod = PyImport_ImportModule("io"))) {
    goto error;
}

io 导入 abc 模块,并将 registers FileIO 作为 RawIOBase 的虚拟子类,还有一些类用于 BufferedIOBase 和其他用于 TextIOBase。在过程中,ABCMeta.register 调用了 __subclasscheck__

正如您所理解的,在 sys.stdout 没有设置的情况下在 __subclasscheck__ 中使用 print 是大忌;初始化失败,您会收到错误信息:

if (initstdio() < 0)
    Py_FatalError(
        "Py_NewInterpreter: can't initialize sys standard streams");

您可以通过使用 hasattr(sys, 'stdout') 进行保护来解决它,此时 sys 已经被初始化,而 stdout 还没有(因此,在早期初始化阶段,sys 中不会存在 stdout)。
if hasattr(sys, 'stdout'):
    print("Debug")

现在启动Python应该会得到大量的输出。


分享一下,以防对某人有所帮助:我给一个模块取名为io.py,这个想法并不好,因为CPython已经导入了一个io模块! - CharlesG

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