2009-01-21 42 views
15

在Unix上,我可以使用\ r(回车)或\ b(退格)打印shell中已经可见的文本(即再次覆盖当前行)。如何在命令行应用程序的当前行上打印?

我可以通过Python脚本在Windows命令行中实现相同效果吗?

我试过curses模块,但它似乎没有在Windows上可用。

+0

我[提问](http://stackoverflow.com/questions/51212/how-to-write-a-download-progress-indicator-in-python)大约一个Python下载进度指标可能会有所帮助。 – cschol 2009-01-21 13:55:28

回答

23

是:

import sys 
import time 

def restart_line(): 
    sys.stdout.write('\r') 
    sys.stdout.flush() 

sys.stdout.write('some data') 
sys.stdout.flush() 
time.sleep(2) # wait 2 seconds... 
restart_line() 
sys.stdout.write('other different data') 
sys.stdout.flush() 
+0

真棒,对于那些想知道的:适用于2.7 – 2016-06-08 11:57:23

+3

如果第二个数据比第一个数据短,第一个数据的字符留在控制台上 – Hilal 2016-08-09 12:19:01

2

,如果你只是想更新前一行简单的方法:

import time 
for i in range(20): 
    print str(i) + '\r', 
    time.sleep(1) 
1

在Windows(Python 3中),似乎工作(没有标准输出直接使用):

import sys 

for i in reversed(range(0,20)): 
    time.sleep(0.1) 
    if(i == 19): 
    print(str(i), end='', file=sys.stdout) 
    else: 
    print("\r{0:{width}".format(str(i), width = w, fill = ' ', align = 'right'), end='', file=sys.stdout) 
    sys.stdout.flush() 
    w = len(str(i)) 

每次打印函数被调用时都会更新相同的行。

该算法可以改进,但它被张贴来显示你可以做什么。您可以根据需要修改该方法。

11
import sys 
import time 

for i in range(10): 
    print '\r',   # print is Ok, and comma is needed. 
    time.sleep(0.3) 
    print i, 
    sys.stdout.flush() # flush is needed. 

如果在IPython的笔记本,就像这样:

import time 
from IPython.display import clear_output 

for i in range(10): 
    time.sleep(0.25) 
    print(i) 
    clear_output(wait=True) 

http://nbviewer.ipython.org/github/ipython/ipython/blob/master/examples/notebooks/Animations%20Using%20clear_output.ipynb

+1

ipython笔记本/ jupyter是我一直在寻找的! – dmeu 2015-08-13 14:28:43

4

我知道这是老了,但我想告诉我的版本(它的作品在我的电脑在cmd中,但不在空闲中)重写Python 3中的一行:

>>> from time import sleep 
>>> for i in range(400): 
>>>  print("\r" + str(i), end="") 
>>>  sleep(0.5) 

编辑: 它适用于Windows和Ubuntu上

5

我刚刚有这个问题。即使在Windows命令提示符下,您仍然可以使用\r,但是,它只会将您带回上一个换行符(\n)。

如果你做这样的事情:

cnt = 0 
print str(cnt) 
while True: 
    cnt += 1 
    print "\r" + str(cnt) 

您将获得:

0 
1 
2 
3 
4 
5 
... 

这是因为\r只追溯到最后一行。由于您已经使用最后一个打印语句编写了换行符,因此您的光标将从新空行的开始处移动到同一个新空行的开始位置。

为了说明,在打印第一个0后,光标会在这里:

0 
| # <-- Cursor 

当你\r,你去行的开头。但是你已经在线的开始。

修正是为了避免打印\n字符,因此您的光标位于同一行,并且\r会正确覆盖文本。你可以用print 'text',来做到这一点。逗号禁止打印换行符。

cnt = 0 
print str(cnt), 
while True: 
    cnt += 1 
    print "\r" + str(cnt), 

现在它会正确地重写行。

请注意,这是Python 2.7,因此是print声明。

5

简单的方法:)

import sys 
from time import sleep 
import os 

#print("\033[y coordinate;[x coordinateH Hello") 
os.system('cls') 
sleep(0.2) 
print("\033[1;1H[]") 
sleep(0.2) 
print("\033[1;1H []") 
sleep(0.2) 
print("\033[1;1H []") 
sleep(0.2) 
print("\033[1;1H  []") 
sleep(0.2) 
print("\033[1;1H  []") 
sleep(0.2) 
print("\033[1;1H  []") 
sleep(0.2) 
print("\033[1;1H []") 
sleep(0.2) 
print("\033[1;1H []") 
sleep(0.2) 
print("\033[1;1H[]") 
sleep(0.2) 
0

感谢您对这里的家伙的所有有用的答案。我需要这个:)

我发现nosklo的答案特别有用,但我希望通过将所需的输出作为参数传递给函数。另外,我并不需要计时器,因为我想在特定事件发生后进行打印)。

这是什么做的把戏对我来说,我希望别人发现它有用:

import sys 

def replace_cmd_line(output): 
    """Replace the last command line output with the given output.""" 
    sys.stdout.write(output) 
    sys.stdout.flush() 
    sys.stdout.write('\r') 
    sys.stdout.flush() 
+0

最后你只需要一个flush()。我不确定`sys.stdout.write(output +'\ r')`会比两个方法调用(因为为字符串分配内存,复制,GC)快得多,因此保持它们分离可能是好的。 – 2017-01-25 09:47:24

1

最简单的方法是使用两个\ r - 一个开头,一个在结尾

for i in range(10000): 
    print('\r'+str(round(i*100/10000))+'% Complete\r'), 

它会很快

相关问题