我编写了一个函数,可以在执行其他函数时将
stdout
和 stderr
捕获到字符串中。一开始似乎可以工作,但是存在 stderr 未正确重置的问题。
它第一次捕获stderr,但第二次,当我希望它使用新缓冲区时,它尝试使用封闭的字符串缓冲区。
这是我的代码:
import io
import sys
import contextlib
from typing import Optional
import logging
def capture_output(
target: object,
args: Optional[tuple] = None,
kwargs: Optional[dict] = None) -> str:
"""Redirect stdout and stderr into string buffer and capture it.
target object is executed with optional args, kwargs and all stdout/
stderr that is captured, returned in string form.
Args:
target: object to execute, usually a function.
args: target positional arguments (default: {None})
kwargs: target keyword arguments (default: {None})
"""
if not args:
args = ()
if not kwargs:
kwargs = {}
# with _setup_capture_output() as sio:
with io.StringIO() as sio:
with contextlib.redirect_stdout(sio), contextlib.redirect_stderr(sio):
target(*args, **kwargs)
output = sio.getvalue()
print(output)
def dummy():
print('dummy test')
logging.warning('dummy test')
def dummy2():
print('dummy2 test')
capture_output(dummy) # works
capture_output(dummy) # won't work anymore.
capture_output(dummy2) # works
capture_output(dummy2) # works
第二次运行
capture_output
(如果需要捕获stderr,如logging.warning
情况),则会出错:
--- Logging error ---
Traceback (most recent call last):
File "/usr/lib/python3.5/logging/__init__.py", line 982, in emit
stream.write(msg)
ValueError: I/O operation on closed file
附注如果我尝试仅捕获标准输出(打印),那么它不会在任何数量的
capture_output
调用上爆炸。
我发现即使显式设置了处理程序,这个问题仍然存在。我将所有细节都包含在上面提到的问题中。
https://github.com/python/cpython/issues/80374
希望有人能给点建议。