在运行测试或通过 cron 运行代码时使 tqdm 的输出静音

Posted

技术标签:

【中文标题】在运行测试或通过 cron 运行代码时使 tqdm 的输出静音【英文标题】:Silence tqdm's output while running tests or running the code via cron 【发布时间】:2016-09-02 15:59:00 【问题描述】:

我正在使用tqdm 显示进度条,同时完成一些长时间运行的 Django 管理命令。它工作得很好(很容易使用!),但是......

当我对我的代码运行单元测试时,我想停止输出进度条。如果我使用 cron 或其他方式在后台运行这些命令,我​​还希望进度条不在输出中。

我看不到做这两件事的简单方法,但也许我错过了什么?

【问题讨论】:

【参考方案1】:

当您需要全局禁用所有tqdm 时,这是非常常见的用例,最好不要更改所有使用它的地方的代码,并且您可能无法控制这些地方。关于实现这样一个特性的讨论持续了很多年,但没有结果(1、2、3、4)。用户需要修补 tqdm 以停止污染日志。我发现的最短方法之一可能是这样的:

from tqdm import tqdm
from functools import partialmethod

tqdm.__init__ = partialmethod(tqdm.__init__, disable=True)

这个想法是默认初始化器的已经支持(但不够)的参数。这还不够,因为您需要在每个实例化 tqdm 的地方添加它,而这是您不想要的,这就是我们修改 __init__ 以使其成为默认值的原因。

补丁独立于导入顺序工作,并将影响所有随后创建的tqdm 对象。

【讨论】:

我刚试过这个,它适用于使用 tqdm 导入的包,根本不需要修改或重写代码。 这非常适合使用 tqdm 语句处理外部依赖项,您不想填满您尝试监控的日志 这是一个完美的答案。您既不需要更改现有代码,也不需要添加任何将被传递的布尔标志。我刚刚将它添加到我的 testing_main.py 的开头,它禁用了测试环境的所有 tqdm 输出。【参考方案2】:

使用“禁用”参数的示例:

from tqdm import tqdm
import time

for i in tqdm(range(10), disable=True):
    time.sleep(1)

【讨论】:

这是一个非常好的答案,截至 2021 年 1 月效果很好。【参考方案3】:

使用mock.patch 将使用它的代码中的tqdm 替换为以下内容:

def notqdm(iterable, *args, **kwargs):
    """
    replacement for tqdm that just passes back the iterable
    useful to silence `tqdm` in tests
    """
    return iterable

在测试中:

import mock

...

    @mock.patch('tested_code_module.tqdm', notqdm)
    def test_method(self):
    ...

【讨论】:

【参考方案4】:

有一个 disable 参数,您可以将其设置为 True 以使任何 tqdm 输出静音(实际上它也会完全跳过进度条计算,而不仅仅是显示)。

要动态切换它,您只需在脚本中添加一个命令行参数,该参数将定义是否设置了disable。这应该适用于单元测试和 cron。

【讨论】:

如何在保持计算的同时禁用显示? @Austin 你的意思是进度条的计算?没有办法,但是既然你没有显示它,那有什么意义呢?只要您通过禁用disable 参数来恢复显示,进度条计算就会恢复。但无论如何,您的应用程序的计算不会受到任何影响,只是禁用了显示的进度条计算。

以上是关于在运行测试或通过 cron 运行代码时使 tqdm 的输出静音的主要内容,如果未能解决你的问题,请参考以下文章

Wordpress Cron作业未运行

测试每周的 cron 作业 [关闭]

Jupyter Notebook 中的 tqdm 重复打印新的进度条

在 Heroku 中运行的 Rails 应用程序的脉冲或 cron 作业

通过 cron 推送

如何连续运行 inotifywait 并将其作为 cron 或守护进程运行?