如何在同一行覆盖之前的输出?
我正在写一个FTP下载器。代码的一部分大概是这样的:
ftp.retrbinary("RETR " + file_name, process)
我调用了一个叫做process的函数来处理回调:
def process(data):
print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!'
file.write(data)
输出的结果大概是这样的:
1784 KB / KB 1829 downloaded!
1788 KB / KB 1829 downloaded!
etc...
但是我希望它能打印这一行,然后下次再打印/刷新它,这样就只会显示一次,我就能看到下载的进度。
这该怎么做呢?
13 个回答
18
你可以看看这个 curses模块的文档 和这个 curses模块的使用指南。
这里有一个非常简单的例子:
import time
import curses
stdscr = curses.initscr()
stdscr.addstr(0, 0, "Hello")
stdscr.refresh()
time.sleep(1)
stdscr.addstr(0, 0, "World! (with curses)")
stdscr.refresh()
47
如果你只想改变一行的内容,可以使用 \r
。\r
的意思是“回车”。它的作用就是把光标移动到当前行的开头,并不会删除任何东西。类似地,\b
可以用来向后移动一个字符。(有些终端可能不支持所有这些功能)
import sys
def process(data):
size_str = os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!'
sys.stdout.write('%s\r' % size_str)
sys.stdout.flush()
file.write(data)
308
这是适用于Python 3.x的代码:
print(os.path.getsize(file_name)/1024+'KB / '+size+' KB downloaded!', end='\r')
这里的end=
这个关键词起到了关键作用——默认情况下,print()
会在输出的最后加上一个换行符(\n
),但你可以用其他字符串来替代它。在这个例子中,使用回车符结束行会把光标移回当前行的开头。因此,对于这种简单的用法,不需要导入sys
模块。其实,print()
还有很多其他的关键词参数,可以用来让代码变得更简单。
如果你想在Python 2.6及以上版本中使用相同的代码,可以在文件的顶部加上以下这一行:
from __future__ import print_function