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

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

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

输出:

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

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

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

我应该怎么做呢?


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

I am new to python and am writing some scripts to automate downloading files from FTP servers, etc. I want to show the progress of the download, but I want it to stay in the same position, such as:

output:

Downloading File FooFile.txt [47%]

I’m trying to avoid something like this:

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

How should I go about doing this?


Duplicate: How can I print over the current line in a command line application?


回答 0

您还可以使用回车符:

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

You can also use the carriage return:

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

回答 1

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.')

Python 2

I like the following:

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

Demo:

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

Demo:

import time

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

PyCharm Debugger Console with Python 3

# 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.')

回答 2

使用类似于curses模块的终端处理库:

curses模块提供了curses库的接口,curses库是便携式高级终端处理的实际标准。

Use a terminal-handling library like the curses module:

The curses module provides an interface to the curses library, the de-facto standard for portable advanced terminal handling.


回答 3

\b多次打印退格字符,然后用新数字覆盖旧数字。

Print the backspace character \b several times, and then overwrite the old number with the new number.


回答 4

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

回答 5

对于Python 3xx:

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

For Python 3xx:

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

回答 6

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

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

A neat solution that has been working for me is:

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

The sys.stdout.flush is important otherwise it gets really clunky and the print("") on for loop exit is also important.

UPDATE: As mentioned in the comments, print also has a flush argument. So the following will also work:

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

回答 7

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