如何覆盖前面的打印到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)