¿Cómo escribo la salida en el mismo lugar en la consola?


158

Soy nuevo en Python y estoy escribiendo algunos scripts para automatizar la descarga de archivos desde servidores FTP, etc. Quiero mostrar el progreso de la descarga, pero quiero que permanezca en la misma posición, como:

salida:

Descargando el archivo FooFile.txt [47%]

Estoy tratando de evitar algo como esto:

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

¿Cómo debo hacer esto?


Duplicado : ¿Cómo puedo imprimir sobre la línea actual en una aplicación de línea de comando?


1
Quizás te interese este módulo fácil de usar, es una barra de progreso de texto. pypi.python.org/pypi/progressbar/2.2
wim

Respuestas:


254

También puede usar el retorno de carro:

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

13
Solución muy común y simple. Nota: si su línea es más larga que el ancho de su terminal, esto se pone feo.
ephemient

55
También tuve que agregar una llamada a sys.stdout.flush () para que el cursor no rebotara
scottm

19
¿Es posible hacer esto con varias líneas? Digamos que tengo tres descargas diferentes, y quiero mostrar el progreso de cada una en su propia línea.
EarlCrapstone

11
Me gusta poner el \ral principio de la línea y agregar un \x1b[Kpara borrar el texto anterior.
augurar

11
Parece que la solución más simple para Python 3 (como se menciona en las respuestas a continuación) es: print("sample text", end='\r", flush=True)
Cyrus

35

Python 2

Me gusta lo siguiente:

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

Manifestación:

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

Manifestación:

import time

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

Consola de depurador PyCharm con 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.')

9
use esto para python 3+: print ('Descargando el archivo FooFile.txt [% d %%] \ r'% i, end = "")
hkoosha

En la consola de PyCharm Debugger, debe aparecer antes del texto. De lo contrario, el texto puede no aparecer en absoluto, o aparecer de manera inconsistente. Agregué la versión que funciona para mí como edición, porque no pude escribir código de varias líneas en esta respuesta. Lo puse en mi esencia para que la gente pueda verlo mientras la edición está esperando aprobación: gist.github.com/yulkang/40168c7729a7a7b96d0116d8b1bc26df
Yul Kang

"\ r" al final de la cadena me funciona en la consola del depurador en PyCharm 2020.1 (PyCharm 2020.1.2 (Community Edition); Build # PC-201.7846.77, construido el 31 de mayo de 2020).
Battey


15

Imprima el carácter de retroceso \bvarias veces y luego sobrescriba el número anterior con el nuevo.


interesante, no había pensado en hacerlo de esa manera.
Chris Ballance

Me gusta esto porque no borra los comandos anteriores (si tiene varias etapas que desea dejar en la pantalla)
Nathan Donnellan

3
El uso del retorno de carro (p print 'Downloading.... \r'. Ej. ) Tampoco borra los datos anteriores, pero evita tener que saber qué tan lejos se debe hacer una copia de seguridad.
cod3monk3y

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

¿Por qué es esto mejor que lo anterior (soy Python n00b, así que disculpe mi ignorancia :-))?
BalinKingOfMoria Reinstale CMs

7

Para Python 3xx:

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

4

Una buena solución que me ha funcionado es:

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

El sys.stdout.flushes importante de lo contrario se pone muy torpe y el print("")de salida de bucle también es importante.

ACTUALIZACIÓN : Como se menciona en los comentarios, printtambién tiene un flushargumento. Entonces lo siguiente también funcionará:

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
En Python moderno, puede proporcionar un argumento de flush=Trueto print, por lo que no hay necesidad de una sys.stdout.flush()llamada adicional .
PM 2Ring

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="")
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.