输出到同一行覆盖以前的输出?

我正在写一个 FTP 下载程序,代码的一部分是这样的:

ftp.retrbinary("RETR " + file_name, 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...

但我希望它打印这一行,下次重新打印/刷新它,所以它只会显示一次,我会看到下载的进度。

怎样才能做到呢?

225138 次浏览

看看 诅咒模块文档咒骂单元

真正基本的例子:

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()

如果您只想更改一行,请使用 \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)

下面是 Python3.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

这是我的小类,可以重新打印文本块。它可以正确地清除前面的文本,这样您就可以用较短的新文本覆盖旧文本,而不会造成混乱。

import re, sys


class Reprinter:
def __init__(self):
self.text = ''


def moveup(self, lines):
for _ in range(lines):
sys.stdout.write("\x1b[A")


def reprint(self, text):
# Clear previous text by overwritig non-spaces with spaces
self.moveup(self.text.count("\n"))
sys.stdout.write(re.sub(r"[^\s]", " ", self.text))


# Print new text
lines = min(self.text.count("\n"), text.count("\n"))
self.moveup(lines)
sys.stdout.write(text)
self.text = text


reprinter = Reprinter()


reprinter.reprint("Foobar\nBazbar")
reprinter.reprint("Foo\nbar")

我发现,对于 python 2.7中的一个简单 print 语句,只需在 '\r'后面的末尾加一个逗号。

print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!\r',

这比其他非 python3解决方案要短,但也更难维护。

可以在字符串末尾加上’r’,在打印函数末尾加上逗号。例如:

print(os.path.getsize(file_name)/1024+'KB / '+size+' KB downloaded!\r'),

我使用的是 spyder 3.3.1-windows 7-python 3.6 虽然可能不需要冲水。 基于这篇文章-“一个 href =”https://github.com/spyder-ide/spyder/issues/3437“ rel =”norefrer“ > https://github.com/spyder-ide/spyder/issues/3437

   #works in spyder ipython console - \r at start of string , end=""
import time
import sys
for i in range(20):
time.sleep(0.5)
print(f"\rnumber{i}",end="")
sys.stdout.flush()

要覆盖 python 中的前一行,只需将 End =’r’添加到 print 函数中,测试下面的示例:

import time
for j in range(1,5):
print('waiting : '+j, end='\r')
time.sleep(1)

Python 3.9

   for j in range(1,5):
print('\rwaiting : '+str(j), end='')