如何在控制台的同一位置写入输出?


158

我是python的新手,正在编写一些脚本来自动从FTP服务器等下载文件。我想显示下载进度,但是我希望它保持不变,例如:

输出:

正在下载文件FooFile.txt [47%]

我正在尝试避免这样的事情:

     Downloading File FooFile.txt [47%]
     Downloading File FooFile.txt [48%]
     Downloading File FooFile.txt [49%]

我应该怎么做呢?


复制如何在命令行应用程序的当前行上打印?


1
您可能对这个易于使用的模块感兴趣,它是一个文本进度栏。 pypi.python.org/pypi/progressbar/2.2
WIM

Answers:


254

您还可以使用回车符:

sys.stdout.write("Download progress: %d%%   \r" % (progress) )
sys.stdout.flush()

13
非常普通和简单的解决方案。注意:如果您的线长超过终端的宽度,这将很难看。
短暂

5
我还必须添加对sys.stdout.flush()的调用,以使光标不会回弹
scottm

19
是否可以用多行来执行此操作?可以说我有三种不同的下载方式,并且我想以自己的方式显示每个下载的进度。
EarlCrapstone 2014年

11
我喜欢将放在\r行的开头,并添加一个\x1b[K以清除前面的文本。
augurar 2014年

11
似乎python 3最简单的解决方案(如下面的答案所述)是: print("sample text", end='\r", flush=True)
Cyrus

35

Python 2

我喜欢以下内容:

print 'Downloading File FooFile.txt [%d%%]\r'%i,

演示:

import time

for i in range(100):
    time.sleep(0.1)
    print 'Downloading File FooFile.txt [%d%%]\r'%i,

Python 3

print('Downloading File FooFile.txt [%d%%]\r'%i, end="")

演示:

import time

for i in range(100):
    time.sleep(0.1)
    print('Downloading File FooFile.txt [%d%%]\r'%i, end="")

带有Python 3的PyCharm调试器控制台

# On PyCharm Debugger console, \r needs to come before the text.
# Otherwise, the text may not appear at all, or appear inconsistently.
# tested on PyCharm 2019.3, Python 3.6

import time

print('Start.')
for i in range(100):
    time.sleep(0.02)
    print('\rDownloading File FooFile.txt [%d%%]'%i, end="")
print('\nDone.')

9
将此用于python 3+:print('Downloading File FooFile.txt [%d %%] \ r'%i,end =“”)
hkoosha 2014年

在PyCharm调试器控制台上,\ r必须位于文本之前。否则,文本可能根本不会出现,也可能会出现不一致的情况。我添加了适用于我的版本作为编辑,因为我不能在此答案中编写多行代码。我把它放在要点上,以便人们在编辑等待批准时可以查看它:gist.github.com/yulkang/40168c7729a7a7b96d0116d8b1bc26df
Yul Kang

字符串末尾的“ \ r”在PyCharm 2020.1(PyCharm 2020.1.2(社区版);版本#PC-201.7846.77,建于2020年5月31日)上的调试器控制台中对我有用。
巴蒂



8
#kinda like the one above but better :P

from __future__ import print_function
from time import sleep

for i in range(101):
  str1="Downloading File FooFile.txt [{}%]".format(i)
  back="\b"*len(str1)
  print(str1, end="")
  sleep(0.1)
  print(back, end="")

为什么这比上面的要好(我是Python n00b,所以请原谅我的无知:-))?
BalinKingOfMoria恢复CM

7

对于Python 3xx:

import time
for i in range(10):
    time.sleep(0.2) 
    print ("\r Loading... {}".format(i)+str(i), end="")

4

一个对我有用的整洁的解决方案是:

from __future__ import print_function
import sys
for i in range(10**6):
    perc = float(i) / 10**6 * 100
    print(">>> Download is {}% complete      ".format(perc), end='\r')
    sys.stdout.flush()
print("")

这个sys.stdout.flush很重要,否则它真的很笨拙,print("")on for循环退出也很重要。

更新:如评论中所述,print也有一个flush参数。因此,以下内容也将起作用:

from __future__ import print_function
for i in range(10**6):
    perc = float(i) / 10**6 * 100
    print(">>> Download is {}% complete      ".format(perc), end='\r', flush=True)
print("")

1
在现代Python中,您可以提供flush=Trueto 的arg print,因此不需要额外的sys.stdout.flush()调用。
下午17年

0
x="A Sting {}"
   for i in range(0,1000000):
y=list(x.format(i))
print(x.format(i),end="")

for j in range(0,len(y)):
    print("\b",end="")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.