我编写了可以在执行其他功能时将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
P.S。如果我尝试仅捕获标准输出(打印),则在任何数量的capture_output
调用中都不会爆炸。