问题:替换Python中的控制台输出
我想知道如何像某些C / C ++程序那样在Python中创建这些漂亮的控制台计数器之一。
我在做一个循环,当前输出如下:
Doing thing 0
Doing thing 1
Doing thing 2
...
更整洁的是只更新最后一行;
X things done.
我已经在许多控制台程序中看到了这一点,并且想知道是否/如何在Python中做到这一点。
I’m wondering how I could create one of those nifty console counters in Python as in certain C/C++-programs.
I’ve got a loop doing things and the current output is along the lines of:
Doing thing 0
Doing thing 1
Doing thing 2
...
what would be neater would be to just have the last line update;
X things done.
I’ve seen this in a number of console programs and am wondering if/how I’d do this in Python.
回答 0
一个简单的解决方案是只"\r"
在字符串之前编写而不添加换行符。如果字符串永远不会变短,那就足够了…
sys.stdout.write("\rDoing thing %i" % i)
sys.stdout.flush()
进度条稍微复杂一点……这是我正在使用的东西:
def startProgress(title):
global progress_x
sys.stdout.write(title + ": [" + "-"*40 + "]" + chr(8)*41)
sys.stdout.flush()
progress_x = 0
def progress(x):
global progress_x
x = int(x * 40 // 100)
sys.stdout.write("#" * (x - progress_x))
sys.stdout.flush()
progress_x = x
def endProgress():
sys.stdout.write("#" * (40 - progress_x) + "]\n")
sys.stdout.flush()
你调用startProgress
传递操作的描述,然后progress(x)
在那里x
是个和最后endProgress()
An easy solution is just writing "\r"
before the string and not adding a newline; if the string never gets shorter this is sufficient…
sys.stdout.write("\rDoing thing %i" % i)
sys.stdout.flush()
Slightly more sophisticated is a progress bar… this is something I am using:
def startProgress(title):
global progress_x
sys.stdout.write(title + ": [" + "-"*40 + "]" + chr(8)*41)
sys.stdout.flush()
progress_x = 0
def progress(x):
global progress_x
x = int(x * 40 // 100)
sys.stdout.write("#" * (x - progress_x))
sys.stdout.flush()
progress_x = x
def endProgress():
sys.stdout.write("#" * (40 - progress_x) + "]\n")
sys.stdout.flush()
You call startProgress
passing the description of the operation, then progress(x)
where x
is the percentage and finally endProgress()
回答 1
一个更优雅的解决方案可能是:
def progressBar(current, total, barLength = 20):
percent = float(current) * 100 / total
arrow = '-' * int(percent/100 * barLength - 1) + '>'
spaces = ' ' * (barLength - len(arrow))
print('Progress: [%s%s] %d %%' % (arrow, spaces, percent), end='\r')
用value
和调用此函数endvalue
,结果应为
Progress: [-------------> ] 69 %
注意:此处为 Python 2.x版本。
A more elegant solution could be:
def progressBar(current, total, barLength = 20):
percent = float(current) * 100 / total
arrow = '-' * int(percent/100 * barLength - 1) + '>'
spaces = ' ' * (barLength - len(arrow))
print('Progress: [%s%s] %d %%' % (arrow, spaces, percent), end='\r')
call this function with value
and endvalue
, result should be
Progress: [-------------> ] 69 %
Note: Python 2.x version here.
回答 2
在python 3中,您可以执行以下操作以在同一行上打印:
print('', end='\r')
跟踪最新更新和进度特别有用。
如果有人想查看循环的进度,我也建议从这里推荐tqdm。它将当前迭代和总迭代打印为带有预期完成时间的进度条。超级有用且快速。适用于python2和python3。
In python 3 you can do this to print on the same line:
print('', end='\r')
Especially useful to keep track of the latest update and progress.
I would also recommend tqdm from here if one wants to see the progress of a loop. It prints the current iteration and total iterations as a progression bar with an expected time of finishing. Super useful and quick. Works for python2 and python3.
回答 3
另一个答案可能更好,但这是我在做什么。首先,我创建了一个名为progress的函数,该函数可以打印出退格字符:
def progress(x):
out = '%s things done' % x # The output
bs = '\b' * 1000 # The backspace
print bs,
print out,
然后我在主函数中循环调用它,如下所示:
def main():
for x in range(20):
progress(x)
return
当然,这会擦除整行,但是您可以将其弄乱以完全执行您想要的操作。我最终使用这种方法制作了一个进度条。
The other answer may be better, but here’s what I was doing. First, I made a function called progress which prints off the backspace character:
def progress(x):
out = '%s things done' % x # The output
bs = '\b' * 1000 # The backspace
print bs,
print out,
Then I called it in a loop in my main function like so:
def main():
for x in range(20):
progress(x)
return
This will of course erase the entire line, but you can mess with it to do exactly what you want. I ended up make a progress bar using this method.
回答 4
对于那些在几年后迷失了方向的人(像我一样),我对6502的方法进行了一些调整,以使进度条既可以增加也可以减少。在更多情况下很有用。感谢6502提供了出色的工具!
基本上,唯一的区别是每次调用progress(x)时都会写入整行#s和-s,并且光标始终返回到小节的开头。
def startprogress(title):
"""Creates a progress bar 40 chars long on the console
and moves cursor back to beginning with BS character"""
global progress_x
sys.stdout.write(title + ": [" + "-" * 40 + "]" + chr(8) * 41)
sys.stdout.flush()
progress_x = 0
def progress(x):
"""Sets progress bar to a certain percentage x.
Progress is given as whole percentage, i.e. 50% done
is given by x = 50"""
global progress_x
x = int(x * 40 // 100)
sys.stdout.write("#" * x + "-" * (40 - x) + "]" + chr(8) * 41)
sys.stdout.flush()
progress_x = x
def endprogress():
"""End of progress bar;
Write full bar, then move to next line"""
sys.stdout.write("#" * 40 + "]\n")
sys.stdout.flush()
For anyone who stumbles upon this years later (like I did), I tweaked 6502’s methods a little bit to allow the progress bar to decrease as well as increase. Useful in slightly more cases. Thanks 6502 for a great tool!
Basically, the only difference is that the whole line of #s and -s is written each time progress(x) is called, and the cursor is always returned to the start of the bar.
def startprogress(title):
"""Creates a progress bar 40 chars long on the console
and moves cursor back to beginning with BS character"""
global progress_x
sys.stdout.write(title + ": [" + "-" * 40 + "]" + chr(8) * 41)
sys.stdout.flush()
progress_x = 0
def progress(x):
"""Sets progress bar to a certain percentage x.
Progress is given as whole percentage, i.e. 50% done
is given by x = 50"""
global progress_x
x = int(x * 40 // 100)
sys.stdout.write("#" * x + "-" * (40 - x) + "]" + chr(8) * 41)
sys.stdout.flush()
progress_x = x
def endprogress():
"""End of progress bar;
Write full bar, then move to next line"""
sys.stdout.write("#" * 40 + "]\n")
sys.stdout.flush()
回答 5
如果我不太了解(不确定),则要使用<CR>
而不是<LR>
?
如果可以的话,只要控制台终端允许这样做(当输出si重定向到文件时,它将中断)。
from __future__ import print_function
print("count x\r", file=sys.stdout, end=" ")
If I understood well (not sure) you want to print using <CR>
and not <LR>
?
If so this is possible, as long the console terminal allows this (it will break when output si redirected to a file).
from __future__ import print_function
print("count x\r", file=sys.stdout, end=" ")
回答 6
如果我们看一下print()
函数,可以不用使用sys库来完成
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
这是我的代码:
def update(n):
for i in range(n):
print("i:",i,sep='',end="\r",flush=True)
#time.sleep(1)
It can be done without using the sys library if we look at the print()
function
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
Here is my code:
def update(n):
for i in range(n):
print("i:",i,sep='',end="\r",flush=True)
#time.sleep(1)
回答 7
我前一段时间写了这篇文章,对此我感到非常满意。随意使用它。
它需要一个index
和total
,也可以选择title
或bar_length
。完成后,用复选标记替换沙漏。
⏳ Calculating: [████░░░░░░░░░░░░░░░░░░░░░] 18.0% done
✅ Calculating: [█████████████████████████] 100.0% done
我提供了一个可以运行以对其进行测试的示例。
import sys
import time
def print_percent_done(index, total, bar_len=50, title='Please wait'):
'''
index is expected to be 0 based index.
0 <= index < total
'''
percent_done = (index+1)/total*100
percent_done = round(percent_done, 1)
done = round(percent_done/(100/bar_len))
togo = bar_len-done
done_str = '█'*int(done)
togo_str = '░'*int(togo)
print(f'\t⏳{title}: [{done_str}{togo_str}] {percent_done}% done', end='\r')
if round(percent_done) == 100:
print('\t✅')
r = 50
for i in range(r):
print_percent_done(i,r)
time.sleep(.02)
我也有一个带有响应进度栏的版本,具体取决于终端宽度,shutil.get_terminal_size()
如果感兴趣的话。
I wrote this a while ago and really happy with it. Feel free to use it.
It takes an index
and total
and optionally title
or bar_length
. Once done, replaces the hour glass with a check-mark.
⏳ Calculating: [████░░░░░░░░░░░░░░░░░░░░░] 18.0% done
✅ Calculating: [█████████████████████████] 100.0% done
I included an example that can be run to test it.
import sys
import time
def print_percent_done(index, total, bar_len=50, title='Please wait'):
'''
index is expected to be 0 based index.
0 <= index < total
'''
percent_done = (index+1)/total*100
percent_done = round(percent_done, 1)
done = round(percent_done/(100/bar_len))
togo = bar_len-done
done_str = '█'*int(done)
togo_str = '░'*int(togo)
print(f'\t⏳{title}: [{done_str}{togo_str}] {percent_done}% done', end='\r')
if round(percent_done) == 100:
print('\t✅')
r = 50
for i in range(r):
print_percent_done(i,r)
time.sleep(.02)
I also have a version with responsive progress bar depending on the terminal width using shutil.get_terminal_size()
if that is of interest.
回答 8
在Aravind Voggu的示例中增加了更多功能:
def progressBar(name, value, endvalue, bar_length = 50, width = 20):
percent = float(value) / endvalue
arrow = '-' * int(round(percent*bar_length) - 1) + '>'
spaces = ' ' * (bar_length - len(arrow))
sys.stdout.write("\r{0: <{1}} : [{2}]{3}%".format(\
name, width, arrow + spaces, int(round(percent*100))))
sys.stdout.flush()
if value == endvalue:
sys.stdout.write('\n\n')
现在,您可以生成多个进度条,而无需替换前一个。
我还添加了 name
了一个固定宽度的值。
对于两次循环两次progressBar()
,结果的使用将类似于:
Added a little bit more functionality to the example of Aravind Voggu:
def progressBar(name, value, endvalue, bar_length = 50, width = 20):
percent = float(value) / endvalue
arrow = '-' * int(round(percent*bar_length) - 1) + '>'
spaces = ' ' * (bar_length - len(arrow))
sys.stdout.write("\r{0: <{1}} : [{2}]{3}%".format(\
name, width, arrow + spaces, int(round(percent*100))))
sys.stdout.flush()
if value == endvalue:
sys.stdout.write('\n\n')
Now you are able to generate multiple progressbars without replacing the previous one.
I’ve also added name
as a value with a fixed width.
For two loops and two times the use of progressBar()
the result will look like:
回答 9
下面的代码将每0.3秒从0到137的消息计数,替换先前的数字。
到后台的符号数=数字位数。
stream = sys.stdout
for i in range(137):
stream.write('\b' * (len(str(i)) + 10))
stream.write("Message : " + str(i))
stream.flush()
time.sleep(0.3)
Below code will count Message from 0 to 137 each 0.3 second replacing previous number.
Number of symbol to backstage = number of digits.
stream = sys.stdout
for i in range(137):
stream.write('\b' * (len(str(i)) + 10))
stream.write("Message : " + str(i))
stream.flush()
time.sleep(0.3)
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。