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

Kri*_*ian 88 python refresh progress-bar

我正在写一个简单的ftp下载器.代码的一部分是这样的:

ftp.retrbinary("RETR " + file_name, process)
Run Code Online (Sandbox Code Playgroud)

我正在调用函数进程来处理回调:

def process(data):
    print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!'
    file.write(data)
Run Code Online (Sandbox Code Playgroud)

和输出是这样的:

1784  KB / KB 1829 downloaded!
1788  KB / KB 1829 downloaded!
etc...   
Run Code Online (Sandbox Code Playgroud)

我希望它打印这一行,然后下次重新打印/刷新它所以它只显示一次,我将看到该下载的进度...

怎么做到呢?

Kud*_*dzu 156

这是Python 3.x的代码:

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

end=关键字是什么做的工作在这里-在默认情况下,print()在一个换行符(结束\n)字符,但可以使用不同的字符串替换.在这种情况下,使用回车符结束该行会将光标返回到当前行的开头.因此,无需sys为此类简单用法导入模块.print()实际上有许多关键字参数可用于大大简化代码.

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

from __future__ import print_function
Run Code Online (Sandbox Code Playgroud)

  • 我发现我需要在字符串的开头包含`\ r``,并设置`end =''`而不是让它工作.当我以`\ r`结尾时,我不认为我的终端喜欢它 (21认同)
  • 在python <3.0中,语句末尾的逗号将阻止"\n":`print"foo",`但是在此之后你还需要刷新才能看到变化:`sys.stdout.flush()` (12认同)
  • 请注意,通过在文件顶部添加以下导入,也可以在python 2.6+中使用print函数:`from __future__ import print_function`. (6认同)
  • 在一个jupyter笔记本中,使用开头的`\ r`和`end =''`工作得最好,最顺畅.如果字符串和`end ='\ r'`也起作用但最后使用`flush = True`和`\ r``但是不顺畅并删除了该行及其换行符. (4认同)
  • 在目前所有的Python 3个版本中,您可以添加`冲水= TRUE`到`打印()`函数,以确保缓冲被刷新(当`\ N`换行符被写入标准线缓冲区只将冲水). (2认同)

Sam*_*lan 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)
Run Code Online (Sandbox Code Playgroud)


And*_*ini 18

看看curses模块文档curses模块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()
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,curses仅适用于Unix.OP没有告诉我们他的应用程序针对哪个操作系统...... (9认同)
  • @AdrienPlisson,我知道这个问题是几年前提出的,但实际上你可以把Curses带到Windows上:http://www.lfd.uci.edu/~gohlke/pythonlibs/#curses (3认同)
  • 我需要它用于Windows (2认同)

Joe*_*ing 13

我正在使用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()
Run Code Online (Sandbox Code Playgroud)


Bou*_*egh 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")
Run Code Online (Sandbox Code Playgroud)

  • 这在 Windows 到 Windows 10 中都不起作用,因为 Windows 10 是第一个支持这些控制字符的窗口 https://en.wikipedia.org/wiki/ANSI_escape_code (2认同)

Ami*_*agh 9

要覆盖 python 中的前一行,您需要的就是将end='\r'添加到 print 函数,测试这个示例:

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


Mat*_*len 7

我发现对于python 2.7中的一个简单的print语句,只需在你的后面放一个逗号'\r'.

print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!\r',
Run Code Online (Sandbox Code Playgroud)

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


Mou*_*leh 5

您可以在字符串的末尾添加 '\r' 并在打印函数的末尾添加一个逗号。例如:

print(os.path.getsize(file_name)/1024+'KB / '+size+' KB downloaded!\r'),
Run Code Online (Sandbox Code Playgroud)


小智 5

Python 3.9

for j in range(1,5):
    print('\rwaiting : '+str(j), end='')
Run Code Online (Sandbox Code Playgroud)