【问题标题】:redirect_stderr does not work (Python 3.5)redirect_stderr 不起作用(Python 3.5)
【发布时间】:2016-07-10 12:13:30
【问题描述】:
#! python3
from contextlib import redirect_stderr
import io

f = io.StringIO()
with redirect_stderr(f):
    # simulates an error
    erd

如上所示,我使用redirect_stderr 函数将stderr 重定向到StringIO 对象。但是,它不起作用,因为错误消息仍然在命令提示符中打印出来:

Traceback (most recent call last):
  File "C:\Users\max\testerr.py", line 8, in <module>
    erd
NameError: name 'erd' is not defined

我在 Python 3.5.1 64 位和 3.5.2 64 位上对其进行了测试,结果相同。

A similar issue in this thread

我也尝试将错误写入链接线程中描述的文件,但运行脚本后文件为空。

【问题讨论】:

  • 我认为erd是在初始化之前访问的。是否可以考虑定义变量或检查是否在函数调用中传入并重新运行?
  • sys.stderr = io.StringIO(),您应该知道错误仍然会引发,因此在 io 对象栏中存储您正在捕获的异常似乎是多余的

标签: python python-3.x std stderr


【解决方案1】:

你需要实际写入stderr,它不是捕获异常的工具。

>>> from contextlib import redirect_stderr
>>> import io
>>> f = io.StringIO()
>>> import sys
>>> with redirect_stderr(f):
...    print('Hello', file=sys.stderr)
...
>>> f.seek(0)
0
>>> f.read()
'Hello\n'

要捕获异常,您需要做更多的工作。您可以使用日志库(外部),或编写自己的异常处理程序,然后使用您的自定义输出。

这是一个快速的东西,它使用一个记录器实例来帮助写入流:

log = logging.getLogger('TEST')
log.addHandler(logging.StreamHandler(stream=f))

def exception_handler(exc_type, exc_value, exc_traceback):
    if issubclass(exc_type, KeyboardInterrupt):
       # Let the system handle things like CTRL+C
       sys.__excepthook__(*args)
    log.error('Exception: ', exc_info=(exc_type, exc_value, exc_traceback))

sys.excepthook = exception_handler
raise RuntimeError('foo')

这里的f 与上面的StringIO 实例相同。运行此代码后,您应该不会在控制台上看到任何回溯,但它会存储在流对象中:

>>> f.seek(0)
0
>>> print(f.read())
Hello
Exception:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: foo

【讨论】:

  • 感谢您的澄清。我假设redirect_stderr 可以让我隐式地抑制标准错误输出。
  • 变量args取自哪里? (sys.__excepthook__ 中使用的那个)。您知道这种方法是否可以在 jupyter notebook 中使用?
猜你喜欢
  • 1970-01-01
  • 2015-12-27
  • 2021-08-13
  • 2018-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多