输出到同一行覆盖以前的输出? python(2.5)

时间:2011-02-04 11:13:48

标签: python refresh progress-bar

我正在写一个简单的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...   

但是我希望它能够打印这一行,然后下次重新打印/刷新它,这样它只会显示一次,我会看到下载的进度......

怎么做?

8 个答案:

答案 0 :(得分:133)

这是Python 3.x的代码:

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

end=关键字是这里的工作 - 默认情况下,print()以换行符(\n)结尾,但可以用不同的字符串替换。在这种情况下,使用回车符结束该行会将光标返回到当前行的开头。因此,没有必要为这种简单的用法导入sys模块。 print()实际上有a number of keyword arguments,可以用来大大简化代码。

要在Python 2.6+上使用相同的代码,请将以下行放在文件的顶部:

from __future__ import print_function

答案 1 :(得分:36)

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

答案 2 :(得分:17)

查看curses module documentationcurses module HOWTO

真正基本的例子:

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

答案 3 :(得分:9)

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

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

答案 4 :(得分:6)

我发现对于python 2.7中的简单打印语句,只需在'\r'之后添加一个逗号。

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

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

答案 5 :(得分:3)

您只需添加' \ r'在字符串的末尾加上打印功能结束时的逗号。例如:

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

答案 6 :(得分:1)

我正在使用spyder 3.3.1-Windows 7-Python 3.6 尽管可能不需要冲洗。 根据此帖子-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()

答案 7 :(得分:0)

要忽略python中的上一行,您需要做的就是将 end ='\ r'添加到打印功能,请测试以下示例:

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