[英]How to overwrite the previous print to stdout?
如果我有以下代码:
for x in range(10):
print(x)
我会得到 output
1
2
etc..
我想做的不是打印换行符,而是想替换以前的值并在同一行上用新值覆盖它。
一种方法是使用回车 (
'\\r'<\/code> ) 字符返回到行首而不前进到下一行。
Python 2.7 向前兼容<\/h3>from __future__ import print_function for x in range(10): print(x, end='\\r') print()<\/code><\/pre>
蟒蛇 2.7<\/h3>
for x in range(10): print '{}\\r'.format(x), print<\/code><\/pre>
Python 2.0-2.6<\/h3>
for x in range(10): print '{0}\\r'.format(x), print<\/code><\/pre>
在后两种情况下(仅限 Python 2),print 语句末尾的逗号告诉它不要转到下一行。 最后一个打印语句前进到下一行,因此您的提示不会覆盖您的最终输出。
线路清洁<\/h1>
如果不能保证新的文本行不短于现有行,那么只需添加一个“清除到行尾”的转义序列,
'\\x1b[1K'<\/code> (
'\\x1b'<\/code> = ESC ):
由于我最终通过 Google 来到这里,但我使用的是 Python 3,以下是它在 Python 3 中的工作方式:
for x in range(10):
print("Progress {:2.1%}".format(x / 10), end="\r")
@Mike DeSimone 的回答<\/a>可能大部分时间都有效。 但...
for x in ['abc', 1]:
print '{}\r'.format(x),
-> 1bc
在访问此线程之前,我有同样的问题。 对我来说 sys.stdout.write 只有在我正确刷新缓冲区时才有效,即
for x in range(10):
sys.stdout.write('\r'+str(x))
sys.stdout.flush()
不刷新,结果仅在脚本结束时打印
禁止换行并打印\\r
。
print 1,
print '\r2'
或写入标准输出:
sys.stdout.write('1')
sys.stdout.write('\r2')
for x in range(10):
time.sleep(0.5) # shows how its working
print("\r {}".format(x), end="")
time.sleep(0.5) 用于显示如何擦除先前的输出并在打印消息开始时打印新输出“\\r”,它将在新输出之前擦除先前的输出。
试试这个:
import time
while True:
print("Hi ", end="\r")
time.sleep(1)
print("Bob", end="\r")
time.sleep(1)
它对我有用。 end="\\r"
部分使其覆盖上一行。
警告!
如果您打印出hi
,然后使用\\r
打印出hello
,您将得到hillo
,因为输出覆盖了前两个字母。 如果你用空格打印出hi
(这里没有显示),那么它将输出hi
。 要解决此问题,请使用\\r
打印出空格。
这是@Nagasaki45 答案的更清洁、更“即插即用”的版本。 与这里的许多其他答案不同,它适用于不同长度的字符串。 它通过清除与最后一行打印的长度一样多的空格来实现这一点。 也可以在 Windows 上运行。
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
我无法让此页面上的任何解决方案适用于IPython<\/strong> ,但@Mike-Desimone 的解决方案的细微变化完成了这项工作:不是用回车终止行,而是用回车开始<\/em>行:
for x in range(10):
print '\r{0}'.format(x),
这适用于 Windows 和 python 3.6
import time
for x in range(10):
time.sleep(0.5)
print(str(x)+'\r',end='')
接受的答案并不完美。 第一次打印的行将保留在那里,如果您的第二次打印没有覆盖整个新行,您将得到垃圾文本。
为了说明问题,将此代码保存为脚本并运行它(或只是看看):
import time
n = 100
for i in range(100):
for j in range(100):
print("Progress {:2.1%}".format(j / 100), end="\r")
time.sleep(0.01)
print("Progress {:2.1%}".format(i / 100))
输出将如下所示:
Progress 0.0%%
Progress 1.0%%
Progress 2.0%%
Progress 3.0%%
对我有用的是在留下永久打印之前清除线路。 随意调整您的具体问题:
import time
ERASE_LINE = '\x1b[2K' # erase line command
n = 100
for i in range(100):
for j in range(100):
print("Progress {:2.1%}".format(j / 100), end="\r")
time.sleep(0.01)
print(ERASE_LINE + "Progress {:2.1%}".format(i / 100)) # clear the line first
现在它按预期打印:
Progress 0.0%
Progress 1.0%
Progress 2.0%
Progress 3.0%
我有点惊讶没有人使用退格字符。 这是使用它的一个。
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')
我使用以下方法创建了一个加载器:
for i in range(10):
print(i*'.', end='\r')
这是我的解决方案! 视窗 10,Python 3.7.1
我不确定为什么这段代码有效,但它完全删除了原始行。 我根据之前的答案编译它。 其他答案只会将行返回到开头,但是如果之后您的行较短,它看起来会像hello
变成byelo
一样混乱。
import sys
#include ctypes if you're on Windows
import ctypes
kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
#end ctypes
def clearline(msg):
CURSOR_UP_ONE = '\033[K'
ERASE_LINE = '\x1b[2K'
sys.stdout.write(CURSOR_UP_ONE)
sys.stdout.write(ERASE_LINE+'\r')
print(msg, end='\r')
#example
ig_usernames = ['beyonce','selenagomez']
for name in ig_usernames:
clearline("SCRAPING COMPLETE: "+ name)
输出 - 每一行都将被重写,没有任何旧文本显示:
SCRAPING COMPLETE: selenagomez
下一行(完全重写在同一行):
SCRAPING COMPLETE: beyonce
(Python3)这对我有用。 如果你只使用 \\010 那么它会留下字符,所以我对其进行了一些调整以确保它覆盖了那里的内容。 这也允许您在第一个打印项目之前有一些东西,并且只删除项目的长度。
print("Here are some strings: ", end="")
items = ["abcd", "abcdef", "defqrs", "lmnop", "xyz"]
for item in items:
print(item, end="")
for i in range(len(item)): # only moving back the length of the item
print("\010 \010", end="") # the trick!
time.sleep(0.2) # so you can see what it's doing
根据之前的答案再做一个答案。
pbar.py 的内容:import sys、shutil、datetime
last_line_is_progress_bar=False
def print2(print_string):
global last_line_is_progress_bar
if last_line_is_progress_bar:
_delete_last_line()
last_line_is_progress_bar=False
print(print_string)
def _delete_last_line():
sys.stdout.write('\b\b\r')
sys.stdout.write(' '*shutil.get_terminal_size((80, 20)).columns)
sys.stdout.write('\b\r')
sys.stdout.flush()
def update_progress_bar(current, total):
global last_line_is_progress_bar
last_line_is_progress_bar=True
completed_percentage = round(current / (total / 100))
current_time=datetime.datetime.now().strftime('%m/%d/%Y-%H:%M:%S')
overhead_length = len(current_time+str(current))+13
console_width = shutil.get_terminal_size((80, 20)).columns - overhead_length
completed_width = round(console_width * completed_percentage / 100)
not_completed_width = console_width - completed_width
sys.stdout.write('\b\b\r')
sys.stdout.write('{}> [{}{}] {} - {}% '.format(current_time, '#'*completed_width, '-'*not_completed_width, current,
completed_percentage),)
sys.stdout.flush()
最好覆盖整行,否则如果新行较短,新行将与旧行混合。
import time, os
for s in ['overwrite!', 'the!', 'whole!', 'line!']:
print(s.ljust(os.get_terminal_size().columns - 1), end="\r")
time.sleep(1)
必须在 Windows 上使用columns - 1
。
这对我有用,在 Windows 中使用 Spyder 中的 Python 3.7.9:
from IPython.display import clear_output
from time import sleep
def print_and_overwrite(text):
'''Remember to add print() after the last print that you want to overwrite.'''
clear_output(wait=True)
print(text, end='\r')
for i in range(15):
#I print the results backwards (from 15 to 1), to test shorter strings
message = "Iteration %d out of 15" %(15-i)
print_and_overwrite(message)
sleep(0.5)
print() #This stops the overwriting
print("This will be on a new line")
无论如何,如果有人想套印(清除)以前在标准输出中打印的许多行,那么这个答案应该对他有帮助。 (感谢 Thijmen Dam 的好文章覆盖以前打印的行)
在 ANSI 控制台中,您可以使用特殊序列:
\033[1A
和\033[K
他们首先举起 cursor,其次 - 完全擦除一行。
清除控制台的示例 (Python 3):
LINE_UP = '\033[1A'
LINE_CLEAR = '\033[K'
CONSOLE_HEIGHT = 24 #lines
def clear_console():
for a in range(CONSOLE_HEIGHT):
print(LINE_UP, end=LINE_CLEAR, flush=True)
或者最终简单地(将清除屏幕并将 cursor 移动到 0,0):
print('\033[2J', end='', flush=True)
如果你只想定位 cursor,那么使用这个:
print('\033[<L>;<C>f', end='', flush=True)
其中<L>
和<C>
对应的是Line和Column。
ANSI转义序列的少数参考
这里有一个简单的代码,对您有用!
import sys
import time
for i in range(10):
sys.stdout.write("\r" + i)
sys.stdout.flush()
time.sleep(1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.