【问题标题】:Redirect both stdout and stderr with python tqdm library使用 python tqdm 库重定向 stdout 和 stderr
【发布时间】:2018-01-25 03:37:43
【问题描述】:

我在 Python 中使用 tqdm 来显示控制台进度条。

我有一个来自另一个库的函数,它偶尔会在 tqdm 循环内同时写入 stdout 和 stderr。我无法破解该函数的源代码。

虽然this doc 展示了如何重定向 sys.stdout,但它并不容易推广到 stderr,因为我只能将 stdout 或 stderr 之一传递给 tqdm 的 __init__ 中的 file= 参数。请参阅this question 及其accepted answer 了解说明问题的最少代码。

如何将两者 stdout 和 stderr 一起重定向?

【问题讨论】:

    标签: python tqdm


    【解决方案1】:

    Python在标准库中为你提供了一些帮助,看contextlib

    >>> import io, sys
    >>> from contextlib import redirect_stdout, redirect_stderr
    >>> from tqdm import tqdm
    >>> def foo():
    ...     print('spam to stdout')
    ...     print('spam to stderr', file=sys.stderr)
    ...     
    >>> out = io.StringIO()
    >>> err = io.StringIO()
    >>> with redirect_stdout(out), redirect_stderr(err):
    ...     for x in tqdm(range(3), file=sys.__stdout__):
    ...         print(x)  # more spam
    ...         foo()
    ...         
    100%|██████████| 3/3 [00:00<00:00, 29330.80it/s]
    >>> out.getvalue()
    '0\nspam to stdout\n1\nspam to stdout\n2\nspam to stdout\n'
    >>> err.getvalue()
    'spam to stderr\nspam to stderr\nspam to stderr\n'
    

    【讨论】:

    • 感谢您的回答,但它一点也不轻松。如果您查看我发布的示例链接,您会发现 tqdm 以非常复杂的方式与 sys.stdout/stderr 交互。
    • 在这种情况下,请您提供MCVE
    • MCVE 在this question 我已链接。它还包含一个关于如何重定向标准输出的解决方案,在我的实验中效果很好。我想要的只是使用该代码重定向输出和错误。
    • 您链接的答案看起来像是我上面显示的一种不好的方法,除了标准输出。 contextlib 重定向对我有用,可以正确捕获来自tqdm 的所有内容。如果它不适合您,请描述如何(即您仍然需要 MCVE)。
    • 不,正如我所说,这不是简单的重定向。您不能只在开始时保存 stdout/stderr 并在结束时恢复它们。 Tqdm 在幕后做了很多工作。我链接的答案也在official tqdm doc 中。您的解决方案以字符串的形式捕获所有内容,这不是进度条的本意。
    猜你喜欢
    • 2014-07-22
    • 1970-01-01
    • 2020-06-02
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    相关资源
    最近更新 更多