如何覆盖前面的打印到Python的标准输出?
如果我有以下代码:
for x in range(10): print x
我会得到的输出
1 2 etc..
我想要做的不是打印一个换行符,而是要replace之前的值,并用同一行上的新值覆盖它。
一种方法是使用回车( '\r'
)字符返回到行的开始而不前进到下一行:
for x in range(10): print '{0}\r'.format(x), print
打印声明结尾的逗号告诉它不要去下一行。 最后的打印语句前进到下一行,以便您的提示不会覆盖您的最终输出。
既然我通过Google结束了这个工作,但是我正在使用Python 3,下面是Python 3中的工作原理:
for x in range(10): print("Progress {:2.1%}".format(x / 10), end="\r")
相关的答案在这里: 我怎样才能压制打印语句后的换行符?
@Mike DeSimone的答案可能大部分时间工作。 但…
for x in ['abc', 1]: print '{}\r'.format(x), -> 1bc
这是因为'\r'
只能返回到行的开头,但不清除输出。
编辑:更好的解决scheme(比我以前的build议)
如果POSIX支持对您来说足够了,那么以下操作将清除当前行并将光标保留在开头:
print '\x1b[2K\r',
它使用ANSI转义码清除terminal行。 更多信息可以在维基百科和这个伟大的谈话中find 。
老答案
我发现的(不太好)解决scheme看起来像这样:
last_x = '' for x in ['abc', 1]: print ' ' * len(str(last_x)) + '\r', print '{}\r'.format(x), last_x = x -> 1
一个好处是,它也将在Windows上工作。
禁止换行并打印\r
。
print 1, print '\r2'
或写入标准输出:
sys.stdout.write('1') sys.stdout.write('\r2')
在访问此主题之前,我有同样的问题。 对我来说,sys.stdout.write只有正确地刷新缓冲区即可
for x in range(10): sys.stdout.write('\r'+str(x)) sys.stdout.flush()
没有冲洗,结果只打印在脚本结束
我无法得到这个页面上的任何解决scheme为IPython工作,但@ Mike-Desimone的解决scheme的一个小的变化做了这个工作:而不是用回车终止行,用回车开始行:
for x in range(10): print '\r{0}'.format(x),
另外,这种方法不需要第二个打印语句。
尝试这个:
import time while True: print("Hi ", end="\r") time.sleep(1) print("Bob", end="\r") time.sleep(1)
它为我工作。 end="\r"
部分正在覆盖上一行。
本质上的东西(你不必读):
这种types的行返回被称为回车,并将光标移动到行的开始。 当你按下回车键时,它所做的是创build一个新行,然后将光标移动到新行,然后将其移动到开始位置(如果尚未)。 这起源于打字机,无论何时,只要将车厢 (顶部的栏杆)推向左边,而不必沿着一条线。 这会覆盖那条线上的内容,但是老的打字机只是把它放在前一个字母的上面,所以看起来很糟糕。 现在你可以买的打字机在写下之前删除任何东西。
我明白这是一个写代码的地方,但我忍不住给了一点历史教训。
如果我有什么不妥,请在下面的评论中告诉我。
for x in range(10): time.sleep(0.5) # shows how its working print("\ri".format(i)), end="")
time.sleep(0.5)是为了显示前一次输出是如何被擦除的,当打印信息开始时,新输出被打印为“\ r”,它将在新输出之前擦除前一次输出。
一个更清洁,更“即插即用”的版本,以@长崎45的答案:
def print_statusline(msg: str): last_msg_length = len(print_statusline.last_msg) if hasattr(print_statusline, 'last_msg') else 0 print(' ' * last_msg_length, end='\r') print(msg, end='\r') sys.stdout.flush() # Some say they needed this, I didn't. print_statusline.last_msg = msg # Then simply use like this: for msg in ["Initializing...", "Initialization successful!"]: print_statusline(msg) time.sleep(1) # If you want to check that the line gets cleared properly: for i in range(9, 0, -1): print_statusline("{}".format(i) * i) time.sleep(0.5)
与不同长度的string正常工作,因为它用空格清除行,不像其他许多答案。 也将在Windows上工作。
我已经使用以下来创build一个加载器:
for i in range(10): print(i*'.', end='\r')
这里有一个简单的代码,可以帮助你!
import sys import time for i in range(10): sys.stdout.write("\r" + i) sys.stdout.flush() time.sleep(1)