我编写了一个简单的控制台应用程序,使用ftplib从FTP服务器上传和下载文件。
我想应用程序显示一些可视化的下载/上传进度为用户;每次下载数据块时,我希望它提供一个进度更新,即使它只是一个数字表示,如百分比。
重要的是,我想避免擦除之前打印到控制台的所有文本(即,我不想在打印更新的进度时“清除”整个终端)。
这似乎是一个相当常见的任务——我如何才能制作一个进度条或类似的可视化输出到我的控制台,同时保留之前的程序输出?
我编写了一个简单的控制台应用程序,使用ftplib从FTP服务器上传和下载文件。
我想应用程序显示一些可视化的下载/上传进度为用户;每次下载数据块时,我希望它提供一个进度更新,即使它只是一个数字表示,如百分比。
重要的是,我想避免擦除之前打印到控制台的所有文本(即,我不想在打印更新的进度时“清除”整个终端)。
这似乎是一个相当常见的任务——我如何才能制作一个进度条或类似的可视化输出到我的控制台,同时保留之前的程序输出?
当前回答
https://pypi.python.org/pypi/progressbar2/3.30.2
Progressbar2是一个很好的基于ascii的命令行progressbar库 导入的时间 进口progressbar
bar = progressbar.ProgressBar()
for i in bar(range(100)):
time.sleep(0.02)
bar.finish()
https://pypi.python.org/pypi/tqdm
TQDM是progressbar2的替代方案,我认为它用于pip3,但我不确定
from tqdm import tqdm
for i in tqdm(range(10000)):
...
其他回答
我意识到我在游戏中迟到了,但这里是我写的一个稍微有点yum风格的(Red Hat)(这里不是100%的准确性,但如果你使用进度条来达到这个准确度,那么你就错了):
import sys
def cli_progress_test(end_val, bar_length=20):
for i in xrange(0, end_val):
percent = float(i) / end_val
hashes = '#' * int(round(percent * bar_length))
spaces = ' ' * (bar_length - len(hashes))
sys.stdout.write("\rPercent: [{0}] {1}%".format(hashes + spaces, int(round(percent * 100))))
sys.stdout.flush()
应该产生如下所示的结果:
Percent: [############## ] 69%
... 括号保持不变,只有哈希值增加。
作为装饰器,这可能会更好。再等一天……
把我在这里找到的一些想法放在一起,加上估计的剩余时间:
import datetime, sys
start = datetime.datetime.now()
def print_progress_bar (iteration, total):
process_duration_samples = []
average_samples = 5
end = datetime.datetime.now()
process_duration = end - start
if len(process_duration_samples) == 0:
process_duration_samples = [process_duration] * average_samples
process_duration_samples = process_duration_samples[1:average_samples-1] + [process_duration]
average_process_duration = sum(process_duration_samples, datetime.timedelta()) / len(process_duration_samples)
remaining_steps = total - iteration
remaining_time_estimation = remaining_steps * average_process_duration
bars_string = int(float(iteration) / float(total) * 20.)
sys.stdout.write(
"\r[%-20s] %d%% (%s/%s) Estimated time left: %s" % (
'='*bars_string, float(iteration) / float(total) * 100,
iteration,
total,
remaining_time_estimation
)
)
sys.stdout.flush()
if iteration + 1 == total:
print
# Sample usage
for i in range(0,300):
print_progress_bar(i, 300)
写入一个\r到控制台。这是一个“回车”,它使它之后的所有文本都在行首回显。喜欢的东西:
def update_progress(progress):
print '\r[{0}] {1}%'.format('#'*(progress/10), progress)
这将给你一些像:[##########]100%
根据上面的建议,我制作了进度条。
然而,我想指出一些缺点
每次刷新进度条时,它将从新一行开始 打印(‘\ r({0}){1} %’。格式('#' * progress* 10, progress)) 是这样的: [] 0% [#] 10% (# #) 20% (# # #) 30%
2.方括号“]”和右边的百分数随着“###”变长而右移。 3.如果表达式'progress / 10'不能返回整数,则会发生错误。
下面的代码将修复上面的问题。
def update_progress(progress, total):
print('\r[{0:10}]{1:>2}%'.format('#' * int(progress * 10 /total), progress), end='')
我写了一个简单的进度条:
def bar(total, current, length=10, prefix="", filler="#", space=" ", oncomp="", border="[]", suffix=""):
if len(border) != 2:
print("parameter 'border' must include exactly 2 symbols!")
return None
print(prefix + border[0] + (filler * int(current / total * length) +
(space * (length - int(current / total * length)))) + border[1], suffix, "\r", end="")
if total == current:
if oncomp:
print(prefix + border[0] + space * int(((length - len(oncomp)) / 2)) +
oncomp + space * int(((length - len(oncomp)) / 2)) + border[1], suffix)
if not oncomp:
print(prefix + border[0] + (filler * int(current / total * length) +
(space * (length - int(current / total * length)))) + border[1], suffix)
正如你所看到的,它有:条的长度,前缀和后缀,填充,空间,文本在条上100%(oncomp)和边界
这里有一个例子:
from time import sleep, time
start_time = time()
for i in range(10):
pref = str((i+1) * 10) + "% "
complete_text = "done in %s sec" % str(round(time() - start_time))
sleep(1)
bar(10, i + 1, length=20, prefix=pref, oncomp=complete_text)
正在进行中:
30% [###### ]
Out on complete:
100% [ done in 9 sec ]