我编写了一个简单的控制台应用程序,使用ftplib从FTP服务器上传和下载文件。
我想应用程序显示一些可视化的下载/上传进度为用户;每次下载数据块时,我希望它提供一个进度更新,即使它只是一个数字表示,如百分比。
重要的是,我想避免擦除之前打印到控制台的所有文本(即,我不想在打印更新的进度时“清除”整个终端)。
这似乎是一个相当常见的任务——我如何才能制作一个进度条或类似的可视化输出到我的控制台,同时保留之前的程序输出?
我编写了一个简单的控制台应用程序,使用ftplib从FTP服务器上传和下载文件。
我想应用程序显示一些可视化的下载/上传进度为用户;每次下载数据块时,我希望它提供一个进度更新,即使它只是一个数字表示,如百分比。
重要的是,我想避免擦除之前打印到控制台的所有文本(即,我不想在打印更新的进度时“清除”整个终端)。
这似乎是一个相当常见的任务——我如何才能制作一个进度条或类似的可视化输出到我的控制台,同时保留之前的程序输出?
当前回答
函数从Greenstick 2.7:
def printProgressBar (iteration, total, prefix = '', suffix = '',decimals = 1, length = 100, fill = '#'):
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filledLength = int(length * iteration // total)
bar = fill * filledLength + '-' * (length - filledLength)
print'\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix),
sys.stdout.flush()
# Print New Line on Complete
if iteration == total:
print()
其他回答
把我在这里找到的一些想法放在一起,加上估计的剩余时间:
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)
根据上面的答案和其他类似的关于CLI进度条的问题,我想我得到了一个普遍的答案。请登录https://stackoverflow.com/a/15860757/2254146查看。
总之,代码是这样的:
import time, sys
# update_progress() : Displays or updates a console progress bar
## Accepts a float between 0 and 1. Any int will be converted to a float.
## A value under 0 represents a 'halt'.
## A value at 1 or bigger represents 100%
def update_progress(progress):
barLength = 10 # Modify this to change the length of the progress bar
status = ""
if isinstance(progress, int):
progress = float(progress)
if not isinstance(progress, float):
progress = 0
status = "error: progress var must be float\r\n"
if progress < 0:
progress = 0
status = "Halt...\r\n"
if progress >= 1:
progress = 1
status = "Done...\r\n"
block = int(round(barLength*progress))
text = "\rPercent: [{0}] {1}% {2}".format( "#"*block + "-"*(barLength-block), progress*100, status)
sys.stdout.write(text)
sys.stdout.flush()
看起来像
百分比:[##########]99.0%
并且,为了添加到堆中,这里有一个你可以使用的对象:
将以下内容添加到新文件progressbar.py中
import sys
class ProgressBar(object):
CHAR_ON = '='
CHAR_OFF = ' '
def __init__(self, end=100, length=65):
self._end = end
self._length = length
self._chars = None
self._value = 0
@property
def value(self):
return self._value
@value.setter
def value(self, value):
self._value = max(0, min(value, self._end))
if self._chars != (c := int(self._length * (self._value / self._end))):
self._chars = c
sys.stdout.write("\r {:3n}% [{}{}]".format(
int((self._value / self._end) * 100.0),
self.CHAR_ON * int(self._chars),
self.CHAR_OFF * int(self._length - self._chars),
))
sys.stdout.flush()
def __enter__(self):
self.value = 0
return self
def __exit__(self, *args, **kwargs):
sys.stdout.write('\n')
可以包含在您的程序中:
import time
from progressbar import ProgressBar
count = 150
print("starting things:")
with ProgressBar(count) as bar:
for i in range(count + 1):
bar.value += 1
time.sleep(0.01)
print("done")
结果:
starting things:
100% [=================================================================]
done
这可能有点“夸张”,但如果经常使用,就很方便了。
写入'\r'将把光标移回行首。
这将显示一个百分比计数器:
import time
import sys
for i in range(100):
time.sleep(1)
sys.stdout.write("\r%d%%" % i)
sys.stdout.flush()
它只有不到10行代码。
要点如下:https://gist.github.com/vladignatyev/06860ec2040cb497f0f3
import sys
def progress(count, total, suffix=''):
bar_len = 60
filled_len = int(round(bar_len * count / float(total)))
percents = round(100.0 * count / float(total), 1)
bar = '=' * filled_len + '-' * (bar_len - filled_len)
sys.stdout.write('[%s] %s%s ...%s\r' % (bar, percents, '%', suffix))
sys.stdout.flush() # As suggested by Rom Ruben