IPython和控制台中重定向sys.stderr的不一致性

1 投票
1 回答
766 浏览
提问于 2025-04-16 23:56

在IPython和Gnome终端的控制台中,将错误信息(sys.stderr)重定向到一个文本文件,结果却不一样。

f=open('std.log','w')
sys.stderr=f
raise Exception,"message goes here"

在IPython中,错误信息会直接显示在屏幕上。

In [13]: run std.py

---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)

/home/xiaohan/code/diving-in-python/htmlparser/std.py in <module>()
      2 f=open('std.log','w')
      3 sys.stderr=f
----> 4 raise Exception,"message goes here"
      5 
      6

Exception: message goes here
WARNING: Failure executing file: <std.py>

但是,如果我直接在控制台运行这个命令。

python std.py 

错误信息就会被隐藏,并且重定向到文本文件里。

有没有人能解释一下这是怎么回事呢?

1 个回答

2

问题不在于写入 stderr,而是 IPython 的 run 命令会拦截异常。当程序出现未处理的异常时,IPython 会把错误信息打印到它自己的控制台上,并且还会显示一个额外的警告(警告:执行文件失败)。这是通过设置一个异常处理函数来实现的,这个函数叫做 sys.excepthook

如果你在测试脚本中明确地写入 sys.stderr,那么它会像预期的那样被写入日志文件。

要查看这个异常处理函数,可以在你的脚本中添加 print(sys.excepthook)。直接执行时,它会显示为 <built-in function excepthook>,而在 IPython 中,它会显示为类似 <bound method InteractiveShell.excepthook of <IPython.iplib.InteractiveShell object at 0x022FA3F0>> 的内容。

撰写回答