在运行测试或通过 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 的输出静音的主要内容,如果未能解决你的问题,请参考以下文章
Jupyter Notebook 中的 tqdm 重复打印新的进度条