在python中覆盖stderr的效果

Eli*_*sha 2 python python-2.7 python-internals

以下代码使python崩溃:

import sys
sys.stdout = sys.stderr = None
print "goodbye world!"
Run Code Online (Sandbox Code Playgroud)

我知道没有真正的理由来编写这样的代码,但我想知道它为什么会崩溃.
我的第一个猜测是print命令失败,因为stdout被覆盖然后,在尝试引发异常时,引发了另一个异常,因为它stderr也被覆盖了.

因此在尝试引发异常时会出现堆栈溢出.

任何人都可以在这里解释背景中真正发生的事情吗?
这是一个堆栈溢出?

Mar*_*ers 5

print语句抛出异常,因为sys.stdout设置为None:

>>> import sys
>>> sys.stdout = None
>>> print "goodbye world!"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'write'
Run Code Online (Sandbox Code Playgroud)

仅此一个例外就足以让Python退出,因为您没有在任何地方处理异常.

但是,您可以设置sys.stderrNone 还有,所以无处这个追踪到被写入.这种情况在PyErr_Display功能上是特殊的:

PyObject *f = PySys_GetObject("stderr");
Py_INCREF(value);
if (f == NULL || f == Py_None)
    fprintf(stderr, "lost sys.stderr\n");
Run Code Online (Sandbox Code Playgroud)

在这里,Python将消息写入原始stderr(由操作系统交给Python的那个,而不是sys.stderr),让你知道它无法告诉你究竟出了什么问题.

不是崩溃,这是Python优雅地处理这种情况.