我正在使用 tqdm 来在完成一些长时间运行的 Django 管理命令时显示进度条。它非常好用,但是当我在代码上运行单元测试时,我希望停止输出进度条。如果我使用 cron 或其他方式在后台运行这些命令,我也希望不要输出进度条。我没有找到简单的方法来实现这两个需求,也许我有所遗漏?
使用“disable”参数的示例:
from tqdm import tqdm
import time
for i in tqdm(range(10), disable=True):
time.sleep(1)
有一个disable
参数,你可以将它设置为True
来禁止任何tqdm
输出(实际上,它将完全跳过进度条计算,而不仅仅是显示)。
要动态切换它,你可以向脚本添加一个命令行参数,以定义是否设置了disable
。这对单元测试和cron都适用。
这是一个非常常见的用例,当您需要全局禁用所有 tqdm
的输出时,最好不要更改使用它的所有地方的代码,而且您可能无法控制。
设置环境变量 TQDM_DISABLE=1
。
注意,变量的确切值并不重要,只需是非空字符串即可。
用户需要修补 tqdm 以阻止污染日志。我找到的最简短的方法之一可能是这样:
from tqdm import tqdm
from functools import partialmethod
tqdm.__init__ = partialmethod(tqdm.__init__, disable=True)
这个想法是将初始化器的已支持(但不足够)参数默认化。它不足够,因为你需要在每个实例化tqdm的地方添加它,而你并不希望这样做,这就是为什么我们修改了__init__
以创建这样一个默认值。
这个补丁与导入的顺序无关,并且会影响所有随后创建的tqdm
对象。
tests/__init__.py
中,然后您就可以继续进行了。 - David258from tqdm import tqdm
上使用它,而不是仅在import tqdm
上使用它;) - Cnlyfrom tqdm import tqdm
,它也可以是 from tqdm.auto import tqdm
。 - Eloy Pérez Torres使用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):
...
tqdm.write
,这段代码也可以用来抑制它们:MODULE_TQDM = "tested_code_module.tqdm"
class NoTQDM:
def __init__(self, iterable, *args, **kwargs):
self.iterable = iterable
def __iter__(self):
for item in self.iterable:
yield item
def write(self, *args, **kwargs):
pass
from unittest import mock
...
@mock.patch(MODULE_TQDM, NoTQDM)
def test_method(self):
...