如何在python中覆盖以前的输出到stdout ?

时间:2022-01-18 00:05:45

If I had the following code:

如果我有以下代码:

for x in range(10):
     print x

I would get the output of

我将得到输出

1
2
etc..

What I would like to do is instead of printing a newline, I want to replace the previous value and overwrite it with the new value on the same line.

我想做的不是打印一条新行,而是替换原来的值,并在同一行上用新值覆盖它。

12 个解决方案

#1


95  

One way is to use the carriage return ('\r') character to return to the start of the line without advancing to the next line:

一种方法是使用回车('\r')字符返回行开始,而不向前移动到下一行:

for x in range(10):
    print '{0}\r'.format(x),
print

The comma at the end of the print statement tells it not to go to the next line. The last print statement advances to the next line so your prompt won't overwrite your final output.

print语句末尾的逗号告诉它不要进入下一行。最后一个打印语句会进入下一行,这样提示符就不会覆盖最终输出。

#2


58  

Since I ended up here via Google but am using Python 3, here's how this would work in Python 3:

因为我最后是通过谷歌结束的但是我使用的是Python 3,这就是Python 3的工作原理:

for x in range(10):
    print("Progress {:2.1%}".format(x / 10), end="\r")

Related answer here: How can I suppress the newline after a print statement?

相关的答案是:如何在打印语句之后抑制换行?

#3


22  

@Mike DeSimone answer will probably work most of the time. But...

@Mike DeSimone的答案可能大部分时候都管用。但是…

for x in ['abc', 1]:
    print '{}\r'.format(x),

-> 1bc

This is because the '\r' only goes back to the beginning of the line but doesn't clear the output.

这是因为“\r”只返回到行开头,而不清除输出。

EDIT: Better solution (than my old proposal below)

If POSIX support is enough for you, the following would clear the current line and leave the cursor at its beginning:

如果POSIX支持对您足够支持,下面将清除当前行并将光标保留在其开头:

print '\x1b[2K\r',

It uses ANSI escape code to clear the terminal line. More info can be found in wikipedia and in this great talk.

它使用ANSI转义代码清除终端行。更多的信息可以在*和这次精彩的演讲中找到。

Old answer

The (not so good) solution I've found looks like this:

我发现的(不是很好的)解决方案是这样的:

last_x = ''
for x in ['abc', 1]:
    print ' ' * len(str(last_x)) + '\r',
    print '{}\r'.format(x),
    last_x = x

-> 1

One advantage is that it will work on windows too.

它的一个优点是也能在windows上运行。

#4


16  

Suppress the newline and print \r.

抑制换行并打印\r。

print 1,
print '\r2'

or write to stdout:

stdout或写:

sys.stdout.write('1')
sys.stdout.write('\r2')

#5


16  

I had the same question before visiting this thread. For me the sys.stdout.write worked only if I properly flush the buffer i.e.

在访问这个帖子之前,我也有同样的问题。对我来说,sys.stdout。只有当我正确地刷新缓冲区时,写入才有效。

for x in range(10):
    sys.stdout.write('\r'+str(x))
    sys.stdout.flush()

Without flushing, the result is printed only at the end out the script

在没有刷新的情况下,结果只在脚本的末尾打印

#6


7  

I couldn't get any of the solutions on this page to work for IPython, but a slight variation on @Mike-Desimone's solution did the job: instead of terminating the line with the carriage return, start the line with the carriage return:

我无法让本页上的任何解决方案适用于IPython,但对@Mike-Desimone解决方案的一个小小的改动就完成了这一任务:不再以回车结束行,而是以回车启动行:

for x in range(10):
    print '\r{0}'.format(x),

Additionally, this approach doesn't require the second print statement.

此外,这种方法不需要第二个print语句。

#7


6  

Try this:

试试这个:

import time
while True:
    print("Hi ", end="\r")
    time.sleep(1)
    print("Bob", end="\r")
    time.sleep(1)

It worked for me. The end="\r" part is making it overwrite the previous line.

它为我工作。结束="\r"部分使它覆盖前一行。

WARNING!

警告!

If you print out hi, then print out hello using \r, you’ll get hillo because the output wrote over the previous two letters. If you print out hi with spaces (which don’t show up here), then it will output hi. To fix this, print out spaces using \r.

如果您打印出hi,然后使用\r打印出hello,您将得到hillo,因为输出是在前两个字母上写的。如果你用空格打印hi(这里不显示),那么它将输出hi。要解决这个问题,请使用\r打印空格。

#8


2  

I have used the following to create a loader:

我使用了以下内容来创建一个加载程序:

for i in range(10):
    print(i*'.', end='\r')

#9


1  

A cleaner, more "plug-and-play", version to @Nagasaki45's answer:

一个更干净,更“即插即用”的版本,@Nagasaki45的回答是:

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)

Works properly with strings of different lengths as it clears the line with spaces, unlike many other answers here. Will also work on Windows.

用不同长度的字符串处理,这样可以清除与空格之间的线,不像这里的其他答案。也会在Windows上运行。

#10


1  

I'm a bit surprised nobody is using the backspace character. Here's one that uses it.

我有点惊讶没有人使用backspace角色。这是一个用它的。

import sys
import time

secs = 1000

while True:
    time.sleep(1)  #wait for a full second to pass before assigning a second
    secs += 1  #acknowledge a second has passed

    sys.stdout.write(str(secs))

    for i in range(len(str(secs))):
        sys.stdout.write('\b')

#11


1  

for x in range(10):
    time.sleep(0.5) # shows how its working
    print("\r {}".format(x), end="")

time.sleep(0.5) is to show how previous output is erased and new output is printed "\r" when its at the start of print message , it gonna erase previous output before new output.

sleep(0.5)是用来显示以前的输出是如何被删除的,新的输出是如何被打印出来的。

#12


-2  

Here a simple code which can be useful for you !

这里有一个简单的代码可以对你有用!

import sys
import time

for i in range(10):
    sys.stdout.write("\r" + i)
    sys.stdout.flush()
    time.sleep(1)

#1


95  

One way is to use the carriage return ('\r') character to return to the start of the line without advancing to the next line:

一种方法是使用回车('\r')字符返回行开始,而不向前移动到下一行:

for x in range(10):
    print '{0}\r'.format(x),
print

The comma at the end of the print statement tells it not to go to the next line. The last print statement advances to the next line so your prompt won't overwrite your final output.

print语句末尾的逗号告诉它不要进入下一行。最后一个打印语句会进入下一行,这样提示符就不会覆盖最终输出。

#2


58  

Since I ended up here via Google but am using Python 3, here's how this would work in Python 3:

因为我最后是通过谷歌结束的但是我使用的是Python 3,这就是Python 3的工作原理:

for x in range(10):
    print("Progress {:2.1%}".format(x / 10), end="\r")

Related answer here: How can I suppress the newline after a print statement?

相关的答案是:如何在打印语句之后抑制换行?

#3


22  

@Mike DeSimone answer will probably work most of the time. But...

@Mike DeSimone的答案可能大部分时候都管用。但是…

for x in ['abc', 1]:
    print '{}\r'.format(x),

-> 1bc

This is because the '\r' only goes back to the beginning of the line but doesn't clear the output.

这是因为“\r”只返回到行开头,而不清除输出。

EDIT: Better solution (than my old proposal below)

If POSIX support is enough for you, the following would clear the current line and leave the cursor at its beginning:

如果POSIX支持对您足够支持,下面将清除当前行并将光标保留在其开头:

print '\x1b[2K\r',

It uses ANSI escape code to clear the terminal line. More info can be found in wikipedia and in this great talk.

它使用ANSI转义代码清除终端行。更多的信息可以在*和这次精彩的演讲中找到。

Old answer

The (not so good) solution I've found looks like this:

我发现的(不是很好的)解决方案是这样的:

last_x = ''
for x in ['abc', 1]:
    print ' ' * len(str(last_x)) + '\r',
    print '{}\r'.format(x),
    last_x = x

-> 1

One advantage is that it will work on windows too.

它的一个优点是也能在windows上运行。

#4


16  

Suppress the newline and print \r.

抑制换行并打印\r。

print 1,
print '\r2'

or write to stdout:

stdout或写:

sys.stdout.write('1')
sys.stdout.write('\r2')

#5


16  

I had the same question before visiting this thread. For me the sys.stdout.write worked only if I properly flush the buffer i.e.

在访问这个帖子之前,我也有同样的问题。对我来说,sys.stdout。只有当我正确地刷新缓冲区时,写入才有效。

for x in range(10):
    sys.stdout.write('\r'+str(x))
    sys.stdout.flush()

Without flushing, the result is printed only at the end out the script

在没有刷新的情况下,结果只在脚本的末尾打印

#6


7  

I couldn't get any of the solutions on this page to work for IPython, but a slight variation on @Mike-Desimone's solution did the job: instead of terminating the line with the carriage return, start the line with the carriage return:

我无法让本页上的任何解决方案适用于IPython,但对@Mike-Desimone解决方案的一个小小的改动就完成了这一任务:不再以回车结束行,而是以回车启动行:

for x in range(10):
    print '\r{0}'.format(x),

Additionally, this approach doesn't require the second print statement.

此外,这种方法不需要第二个print语句。

#7


6  

Try this:

试试这个:

import time
while True:
    print("Hi ", end="\r")
    time.sleep(1)
    print("Bob", end="\r")
    time.sleep(1)

It worked for me. The end="\r" part is making it overwrite the previous line.

它为我工作。结束="\r"部分使它覆盖前一行。

WARNING!

警告!

If you print out hi, then print out hello using \r, you’ll get hillo because the output wrote over the previous two letters. If you print out hi with spaces (which don’t show up here), then it will output hi. To fix this, print out spaces using \r.

如果您打印出hi,然后使用\r打印出hello,您将得到hillo,因为输出是在前两个字母上写的。如果你用空格打印hi(这里不显示),那么它将输出hi。要解决这个问题,请使用\r打印空格。

#8


2  

I have used the following to create a loader:

我使用了以下内容来创建一个加载程序:

for i in range(10):
    print(i*'.', end='\r')

#9


1  

A cleaner, more "plug-and-play", version to @Nagasaki45's answer:

一个更干净,更“即插即用”的版本,@Nagasaki45的回答是:

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)

Works properly with strings of different lengths as it clears the line with spaces, unlike many other answers here. Will also work on Windows.

用不同长度的字符串处理,这样可以清除与空格之间的线,不像这里的其他答案。也会在Windows上运行。

#10


1  

I'm a bit surprised nobody is using the backspace character. Here's one that uses it.

我有点惊讶没有人使用backspace角色。这是一个用它的。

import sys
import time

secs = 1000

while True:
    time.sleep(1)  #wait for a full second to pass before assigning a second
    secs += 1  #acknowledge a second has passed

    sys.stdout.write(str(secs))

    for i in range(len(str(secs))):
        sys.stdout.write('\b')

#11


1  

for x in range(10):
    time.sleep(0.5) # shows how its working
    print("\r {}".format(x), end="")

time.sleep(0.5) is to show how previous output is erased and new output is printed "\r" when its at the start of print message , it gonna erase previous output before new output.

sleep(0.5)是用来显示以前的输出是如何被删除的,新的输出是如何被打印出来的。

#12


-2  

Here a simple code which can be useful for you !

这里有一个简单的代码可以对你有用!

import sys
import time

for i in range(10):
    sys.stdout.write("\r" + i)
    sys.stdout.flush()
    time.sleep(1)