Python3-重定向的stderr无法正确重置?

时间:2019-03-05 09:39:05

标签: python python-3.x stdout stderr

我编写了可以在执行其他功能时将stdoutstderr捕获为字符串的函数。乍看起来似乎可以,但是存在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调用中都不会爆炸。

0 个答案:

没有答案