Estoy escribiendo un descargador de FTP. Parte del código es algo como esto:
ftp.retrbinary("RETR " + file_name, process)
Estoy llamando al proceso de función para manejar la devolución de llamada:
def process(data):
print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!'
file.write(data)
y la salida es algo como esto:
1784 KB / KB 1829 downloaded!
1788 KB / KB 1829 downloaded!
etc...
pero quiero que imprima esta línea y la próxima vez la vuelva a imprimir / actualice para que solo la muestre una vez y veré el progreso de esa descarga.
¿Cómo puede hacerse esto?
python
refresh
progress-bar
Kristian
fuente
fuente
Respuestas:
Aquí está el código para Python 3.x:
La
end=
palabra clave es lo que funciona aquí; de forma predeterminada,print()
termina en un carácter de nueva línea (\n
), pero esto se puede reemplazar con una cadena diferente. En este caso, terminar la línea con un retorno de carro devuelve el cursor al inicio de la línea actual. Por lo tanto, no es necesario importar elsys
módulo para este tipo de uso simple.print()
en realidad tiene una serie de argumentos de palabras clave que pueden usarse para simplificar mucho el código.Para usar el mismo código en Python 2.6+, coloque la siguiente línea en la parte superior del archivo:
fuente
from __future__ import print_function
.print "foo",
Sin embargo, aún necesita descargar después de eso para ver el cambio:sys.stdout.flush()
\r
al comienzo de la cadena y configurarloend=''
para que esto funcione. No creo que a mi terminal le guste cuando termino con\r
flush=True
a laprint()
función para asegurarse de que el búfer se vacíe (el búfer de línea estándar solo se eliminaría cuando\n
se escribe una nueva línea).\r
al principio yend=''
funcionó mejor y más suave. Usarflush=True
con\r
al final si la cuerda yend='\r'
también funcionó pero no fue suave y borró la línea y su salto de línea.Si todo lo que desea hacer es cambiar una sola línea, use
\r
.\r
significa retorno de carro. Su efecto es únicamente volver a colocar el símbolo de intercalación al comienzo de la línea actual. No borra nada. De manera similar,\b
se puede usar para retroceder un carácter. (es posible que algunos terminales no admitan todas esas funciones)fuente
\r
significa retorno de carro. su efecto es únicamente volver a colocar el símbolo de intercalación al comienzo de la línea actual. no borra nada. de manera similar,\b
se puede usar para retroceder un carácter. (Es posible que algunos terminales no admitan todas esas funciones)sys.stdout.write('%s\r', size_str')
Creo que te refieres asys.stdout.write('%s\r' % size_str)
pero no funciona.print
lugar desys.stdout.write
si lo prefiere:print size_str + "\r",
funciona bien. El,
al final de la declaración de impresión suprime la nueva línea;sys.stdout.flush()
todavía se necesitaEche un vistazo a la documentación del módulo de curses y al HOWTO del módulo de curses .
Ejemplo realmente básico:
fuente
clrtoeol
para cuando la segunda línea sea más corta que la primera.Aquí está mi pequeña clase que puede reimprimir bloques de texto. Borra correctamente el texto anterior para que pueda sobrescribir su texto anterior con texto nuevo más corto sin crear un lío.
fuente
Descubrí que para una declaración de impresión simple en Python 2.7, simplemente coloque una coma al final después de su
'\r'
.Esto es más corto que otras soluciones que no son de Python 3, pero también más difícil de mantener.
fuente
Simplemente puede agregar '\ r' al final de la cadena más una coma al final de la función de impresión. Por ejemplo:
fuente
end
parámetro predeterminado configurado para\n
imprimir(...)KB downloaded!\r\n
. ¿Me equivoco?end = '\r'
lugar soluciona el problema en Python 3.Estoy usando spyder 3.3.1 - windows 7 - python 3.6 aunque es posible que no se necesite flush. basado en esta publicación - https://github.com/spyder-ide/spyder/issues/3437
fuente
para sobrepasar la línea anterior en Python, todo lo que necesita es agregar end = '\ r' a la función de impresión, pruebe este ejemplo:
fuente