tqdm 打印到换行符
tqdm printing to newline
我正在 python 开发一个小型命令行游戏,我在其中使用 tqdm 模块显示进度条。我使用 msvcrt 模块监听用户输入以中断进程。一旦中断,用户可以通过在命令行提示符中输入 'restart' 来重新启动。第二次显示进度条时,它不会根据进度更新同一行,而是每次都创建一个新行。
如何让它在同一行显示进度?
此代码片段说明了我对进度条的使用。
def transfer():
for i in tqdm.tqdm(range(1000), desc="Transfer progress", ncols=100, bar_format='{l_bar}{bar}|'):
sleep(.1)
if msvcrt.kbhit():
if msvcrt.getwche() == ' ':
interrupt()
break
def interrupt():
type("File transfer interrupted, to restart the transfer, type 'restart'")
尝试 from tqdm import tqdm_notebook as tqdm
而不是 from tqdm import tqdm
。
尝试使用 tqdm.tqdm.write
代替标准 print()
这将在进度条上方打印并将进度条向下移动一行。
我使用下面的代码对此进行了测试,按 space
将打印到标准输出但不会中断循环。
并不是 100% 清楚您要实现的目标,因为您的 interrupt()
函数仅检查提供的字符串的类型。 type() built-in function
import tqdm
import msvcrt
from time import sleep
def transfer():
for i in tqdm.tqdm(range(1000), desc="Transfer progress", ncols=100, bar_format='{l_bar}{bar}|'):
sleep(.1)
if msvcrt.kbhit():
if msvcrt.getwche() == ' ':
interrupt()
# break
def interrupt():
tqdm.tqdm.write("File transfer interrupted, to restart the transfer, type 'restart'", end="")
transfer()
编辑:包含 tqdm.write()
的 end
参数,如 Paul Netherwood 所述
tqdm.tqdm.write()
尝试使用 tqdm.tnrange()
for i in tqdm.tnrange(len(df)):
试试 position=0
和 leave=True
(解决方案在 Google Colab 中工作以避免打印到换行符)
from tqdm import tqdm
import time
def foo_():
time.sleep(0.3)
range_ = range(0, 10)
total = len(range_)
with tqdm(total=total, position=0, leave=True) as pbar:
for i in tqdm((foo_, range_ ), position=0, leave=True):
pbar.update()
我已经尝试过 tqdm 解决方案,但由于我使用的是 Spyder (Anaconda),它在我的情况下不起作用,因为在其他答案中提到写入和打印命令之间存在冲突。我想出了一个简单且有效但不是最奇特的解决方案。
def ybar(progr, total, step=50):
#starts with 1
l2=(progr/total)//(1/step)
if progr==1: print(f'[{total}]: '+'|'*int(l2), end = '')
else:
l1=((progr-1)/total)//(1/step)
ll=int(l2-l1)
if l1 < l2:
for j in range(1,ll+1):
if (int(l1)+j)%5==0:
print('*', end = '')
else:
print('|', end = '')
if progr==total: print(" DONE")
结果你会变得简单:[100]: ||||||
for i in range(1,101):
ybar(i,len(range(1,101)),50)
#something
这里有很多解决方案:Python Progress Bar
以下是 hacky,但似乎可以很好地重置 tqdm:
from tqdm import tqdm as tqdm_base
def tqdm(*args, **kwargs):
if hasattr(tqdm_base, '_instances'):
for instance in list(tqdm_base._instances):
tqdm_base._decr_instances(instance)
return tqdm_base(*args, **kwargs)
有时前面的输出会打印在开头(我不确定如何删除),但我发现它比换行更不烦人(尤其是在长循环中)。
导入tqdm
.
from tqdm import tqdm
首先开始代码,在你使用tqdm
的地方,因为多行输出停止它。
然后做:
list(getattr(tqdm, '_instances'))
for instance in list(tqdm._instances):
tqdm._decr_instances(instance)
如果出现错误:
AttributeError: type object 'tqdm' has no attribute '_instances'
您需要首先开始您的代码,在您使用tqdm
的地方,然后才开始提到的代码。
在所有这些操作之后,您的 tqdm
将正常工作。
from tqdm import tqdm_notebook
此命令适用于 google colab。
tqdm_notebook 已弃用。您必须改用 tq.notebook.tqdm。
import tqdm.notebook as tq
for i in tq.tqdm(...):
而且tqdm_notebook在表演方面真的很惨。新库完全纠正了这一点。
我已经意识到在再次使用 tqdm 之前关闭 tqdm 实例可以解决在 Jupyter Lab 上以新行打印状态栏的问题:
while len(tqdm._instances) > 0:
tqdm._instances.pop().close()
或者更好,感谢 Nirmal 的建议:
tqdm._instances.clear()
您可能导入了两次 tqdm。重新启动整个笔记本内核并再次 运行。它将解决问题。由于 tqdm
中的任何打印语句,它也可能会显示
from tqdm import notebook
而不是tqdm(looping)
使用 notebook.tqdm(looping)
leave=False
内部循环在我的案例中有效。
for j in tqdm(outer_list):
for i in tqdm(inner_list, leave=False):
环境 tqdm==4.38.0
和 Python 3.6.7
https://github.com/tqdm/tqdm#parameters
我认为有时 tqdm 无法捕获屏幕宽度
使用 ncols=xx 限制线宽
前任:
tqdm(iter,ncols=80): # 限制线宽=80
除了前面提到的 position=0, leave=True
参数,在我的例子中,tqdm
的默认 ascii=False
参数也在几次迭代后打印在新行上。您可以通过查看进度条轻松确定是否属于这种情况:如果进度条中有任何格式奇怪的符号(例如问号),您应该尝试使用 ascii=True
.
所以这对我有用:
from tqdm.auto import tqdm
...
with tqdm(data, position=0, leave=True, ascii=True) as iterator:
for x in iterator:
# do stuff
...
iterator.set_postfix_str(msg)
我经常遇到这个问题,有时 position = 0
& leave = True
不起作用。所以,我找到了另一种方法。
您可以使用 tqdm.tqdm 而不是 tqdm.auto.tqdm
或
而不是
from tqdm import tqdm
尝试使用
from tqdm.auto import tqdm
我遇到的问题可能并不常见,但如果它对任何人都有用,我正在将另一个变量打印到控制台。禁用该打印可解决问题。
如果您在 colab 或 jupyter notebook 上使用 tqdm
时遇到此问题,那么 ...
使用 notebook/colab 版本的 tqdm
>>> from tqdm.notebook import trange, tqdm
>>> for i in trange(1000):
... ...
我正在 python 开发一个小型命令行游戏,我在其中使用 tqdm 模块显示进度条。我使用 msvcrt 模块监听用户输入以中断进程。一旦中断,用户可以通过在命令行提示符中输入 'restart' 来重新启动。第二次显示进度条时,它不会根据进度更新同一行,而是每次都创建一个新行。
如何让它在同一行显示进度?
此代码片段说明了我对进度条的使用。
def transfer():
for i in tqdm.tqdm(range(1000), desc="Transfer progress", ncols=100, bar_format='{l_bar}{bar}|'):
sleep(.1)
if msvcrt.kbhit():
if msvcrt.getwche() == ' ':
interrupt()
break
def interrupt():
type("File transfer interrupted, to restart the transfer, type 'restart'")
尝试 from tqdm import tqdm_notebook as tqdm
而不是 from tqdm import tqdm
。
尝试使用 tqdm.tqdm.write
代替标准 print()
这将在进度条上方打印并将进度条向下移动一行。
我使用下面的代码对此进行了测试,按 space
将打印到标准输出但不会中断循环。
并不是 100% 清楚您要实现的目标,因为您的 interrupt()
函数仅检查提供的字符串的类型。 type() built-in function
import tqdm
import msvcrt
from time import sleep
def transfer():
for i in tqdm.tqdm(range(1000), desc="Transfer progress", ncols=100, bar_format='{l_bar}{bar}|'):
sleep(.1)
if msvcrt.kbhit():
if msvcrt.getwche() == ' ':
interrupt()
# break
def interrupt():
tqdm.tqdm.write("File transfer interrupted, to restart the transfer, type 'restart'", end="")
transfer()
编辑:包含 tqdm.write()
的 end
参数,如 Paul Netherwood 所述
tqdm.tqdm.write()
尝试使用 tqdm.tnrange()
for i in tqdm.tnrange(len(df)):
试试 position=0
和 leave=True
(解决方案在 Google Colab 中工作以避免打印到换行符)
from tqdm import tqdm
import time
def foo_():
time.sleep(0.3)
range_ = range(0, 10)
total = len(range_)
with tqdm(total=total, position=0, leave=True) as pbar:
for i in tqdm((foo_, range_ ), position=0, leave=True):
pbar.update()
我已经尝试过 tqdm 解决方案,但由于我使用的是 Spyder (Anaconda),它在我的情况下不起作用,因为在其他答案中提到写入和打印命令之间存在冲突。我想出了一个简单且有效但不是最奇特的解决方案。
def ybar(progr, total, step=50):
#starts with 1
l2=(progr/total)//(1/step)
if progr==1: print(f'[{total}]: '+'|'*int(l2), end = '')
else:
l1=((progr-1)/total)//(1/step)
ll=int(l2-l1)
if l1 < l2:
for j in range(1,ll+1):
if (int(l1)+j)%5==0:
print('*', end = '')
else:
print('|', end = '')
if progr==total: print(" DONE")
结果你会变得简单:[100]: ||||||
for i in range(1,101):
ybar(i,len(range(1,101)),50)
#something
这里有很多解决方案:Python Progress Bar
以下是 hacky,但似乎可以很好地重置 tqdm:
from tqdm import tqdm as tqdm_base
def tqdm(*args, **kwargs):
if hasattr(tqdm_base, '_instances'):
for instance in list(tqdm_base._instances):
tqdm_base._decr_instances(instance)
return tqdm_base(*args, **kwargs)
有时前面的输出会打印在开头(我不确定如何删除),但我发现它比换行更不烦人(尤其是在长循环中)。
导入tqdm
.
from tqdm import tqdm
首先开始代码,在你使用tqdm
的地方,因为多行输出停止它。
然后做:
list(getattr(tqdm, '_instances'))
for instance in list(tqdm._instances):
tqdm._decr_instances(instance)
如果出现错误:
AttributeError: type object 'tqdm' has no attribute '_instances'
您需要首先开始您的代码,在您使用tqdm
的地方,然后才开始提到的代码。
在所有这些操作之后,您的 tqdm
将正常工作。
from tqdm import tqdm_notebook
此命令适用于 google colab。
tqdm_notebook 已弃用。您必须改用 tq.notebook.tqdm。
import tqdm.notebook as tq
for i in tq.tqdm(...):
而且tqdm_notebook在表演方面真的很惨。新库完全纠正了这一点。
我已经意识到在再次使用 tqdm 之前关闭 tqdm 实例可以解决在 Jupyter Lab 上以新行打印状态栏的问题:
while len(tqdm._instances) > 0:
tqdm._instances.pop().close()
或者更好,感谢 Nirmal 的建议:
tqdm._instances.clear()
您可能导入了两次 tqdm。重新启动整个笔记本内核并再次 运行。它将解决问题。由于 tqdm
中的任何打印语句,它也可能会显示from tqdm import notebook
而不是tqdm(looping)
使用 notebook.tqdm(looping)
leave=False
内部循环在我的案例中有效。
for j in tqdm(outer_list):
for i in tqdm(inner_list, leave=False):
环境 tqdm==4.38.0
和 Python 3.6.7
https://github.com/tqdm/tqdm#parameters 我认为有时 tqdm 无法捕获屏幕宽度 使用 ncols=xx 限制线宽 前任: tqdm(iter,ncols=80): # 限制线宽=80
除了前面提到的 position=0, leave=True
参数,在我的例子中,tqdm
的默认 ascii=False
参数也在几次迭代后打印在新行上。您可以通过查看进度条轻松确定是否属于这种情况:如果进度条中有任何格式奇怪的符号(例如问号),您应该尝试使用 ascii=True
.
所以这对我有用:
from tqdm.auto import tqdm
...
with tqdm(data, position=0, leave=True, ascii=True) as iterator:
for x in iterator:
# do stuff
...
iterator.set_postfix_str(msg)
我经常遇到这个问题,有时 position = 0
& leave = True
不起作用。所以,我找到了另一种方法。
您可以使用 tqdm.tqdm 而不是 tqdm.auto.tqdm
或
而不是
from tqdm import tqdm
尝试使用
from tqdm.auto import tqdm
我遇到的问题可能并不常见,但如果它对任何人都有用,我正在将另一个变量打印到控制台。禁用该打印可解决问题。
如果您在 colab 或 jupyter notebook 上使用 tqdm
时遇到此问题,那么 ...
使用 notebook/colab 版本的 tqdm
>>> from tqdm.notebook import trange, tqdm
>>> for i in trange(1000):
... ...