更新时间:2023-10-23 11:56:28
你需要真正写入 stderr,它不是捕捉异常的工具.
>>>从 contextlib 导入 redirect_stderr>>>导入 io>>>f = io.StringIO()>>>导入系统>>>使用 redirect_stderr(f):...打印('你好',文件= sys.stderr)...>>>f.seek(0)0>>>f.read()'你好\n'要捕获异常,您需要做更多的工作.您可以使用日志库(外部),或编写自己的异常处理程序,然后使用您的自定义输出.
这里有一些快速的东西,它使用一个记录器实例来帮助写入流:
log = logging.getLogger('TEST')log.addHandler(logging.StreamHandler(stream=f))def exception_handler(exc_type, exc_value, exc_traceback):如果是子类(exc_type,KeyboardInterrupt):# 让系统处理诸如CTRL+C之类的事情sys.__excepthook__(*args)log.error('异常:', exc_info=(exc_type, exc_value, exc_traceback))sys.excepthook = 异常处理程序引发运行时错误('foo')
这里的 f
是与上面相同的 StringIO
实例.运行此代码后,您不应在控制台上看到任何回溯,但它会存储在流对象中:
#! python3
from contextlib import redirect_stderr
import io
f = io.StringIO()
with redirect_stderr(f):
# simulates an error
erd
As seen above, I have used the redirect_stderr
function to redirect stderr to a StringIO
object. However, it doesn't work, as the error message is still printed out in command prompt:
Traceback (most recent call last):
File "C:\Users\max\testerr.py", line 8, in <module>
erd
NameError: name 'erd' is not defined
I tested it on Python 3.5.1
64 bit and 3.5.2
64 bit with the same results.
A similar issue in this thread
I have also tried writing the error to a file as described in the linked thread, but the file is empty after running the script.
You need to actually write to stderr, it is not a tool to catch exceptions.
>>> 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'
To catch exceptions, you need to do some more work. You can use a logging library (external), or write your own exception handler, and then use your custom output for it.
Here is something quick, which uses a logger instance to help write to the stream:
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')
Here f
is the same StringIO
instance from above. After you run this code, you should not see any traceback on your console, but it will be stored in the stream object:
>>> f.seek(0)
0
>>> print(f.read())
Hello
Exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: foo