2009-01-21 24 views
15

En Unix, puedo usar \ r (retorno de carro) o \ b (retroceso) para imprimir sobre el texto ya visible en el depósito (es decir, sobrescribir la línea actual de nuevo).¿Cómo puedo imprimir sobre la línea actual en una aplicación de línea de comando?

¿Puedo obtener el mismo efecto en una línea de comandos de Windows desde un script de Python?

He probado el módulo curses pero parece que no está disponible en Windows.

+0

Mi [pregunta] (http://stackoverflow.com/questions/51212/how-to-write-a-download-progress-indicator-in-python) sobre un pitón Descargar El indicador de progreso puede ser útil. – cschol

Respuesta

23

sí:

import sys 
import time 

def restart_line(): 
    sys.stdout.write('\r') 
    sys.stdout.flush() 

sys.stdout.write('some data') 
sys.stdout.flush() 
time.sleep(2) # wait 2 seconds... 
restart_line() 
sys.stdout.write('other different data') 
sys.stdout.flush() 
+0

impresionante, para aquellos que se preguntan: funciona con 2.7 –

+3

Si el segundo dato es más corto que el primero, los caracteres de los primeros datos quedan en la consola – Hilal

2

manera simple si sólo está queriendo actualizar la línea anterior:

import time 
for i in range(20): 
    print str(i) + '\r', 
    time.sleep(1) 
1

En Windows (Python 3), parece que funciona (no usar directamente la salida estándar):

función de impresión cada vez que
import sys 

for i in reversed(range(0,20)): 
    time.sleep(0.1) 
    if(i == 19): 
    print(str(i), end='', file=sys.stdout) 
    else: 
    print("\r{0:{width}".format(str(i), width = w, fill = ' ', align = 'right'), end='', file=sys.stdout) 
    sys.stdout.flush() 
    w = len(str(i)) 

La misma línea se actualiza se llama.

Este algoritmo se puede mejorar, pero se publica para mostrar lo que puede hacer. Puede modificar el método de acuerdo a sus necesidades.

11
import sys 
import time 

for i in range(10): 
    print '\r',   # print is Ok, and comma is needed. 
    time.sleep(0.3) 
    print i, 
    sys.stdout.flush() # flush is needed. 

Y si en el IPython-bloc de notas, al igual que este:

import time 
from IPython.display import clear_output 

for i in range(10): 
    time.sleep(0.25) 
    print(i) 
    clear_output(wait=True) 

http://nbviewer.ipython.org/github/ipython/ipython/blob/master/examples/notebooks/Animations%20Using%20clear_output.ipynb

+1

ipython notebook/jupyter es lo que estaba buscando. – dmeu

4

Sé que esto es viejo, pero yo quería contar mi versión (que funciona en mi PC en el cmd, pero no en el inactivo) para anular una línea en Python 3:

>>> from time import sleep 
>>> for i in range(400): 
>>>  print("\r" + str(i), end="") 
>>>  sleep(0.5) 

EDITAR: Funciona en Windows y en Ubuntu

5

Acabo de tener este problema. Todavía puede usar \r, incluso en el símbolo del sistema de Windows, sin embargo, solo lo lleva al salto de línea anterior (\n).

Si haces algo como esto:

cnt = 0 
print str(cnt) 
while True: 
    cnt += 1 
    print "\r" + str(cnt) 

que obtendrá:

0 
1 
2 
3 
4 
5 
... 

Eso es porque \r solamente se remonta a la última línea. Como ya escribió un carácter de línea nueva con la última instrucción de impresión, el cursor va desde el comienzo de una nueva línea vacía hasta el comienzo de la misma nueva línea vacía.

Para ilustrar, después de imprimir el primer 0, el cursor estaría aquí:

0 
| # <-- Cursor 

Cuando \r, vas al principio de la línea. Pero ya estás en el comienzo de la línea.

La solución es evitar imprimir un carácter \n, por lo que el cursor está en la misma línea y \r sobrescribe el texto correctamente. Puedes hacerlo con print 'text',. La coma impide la impresión de un carácter de nueva línea.

cnt = 0 
print str(cnt), 
while True: 
    cnt += 1 
    print "\r" + str(cnt), 

Ahora reescribirá correctamente las líneas.

Tenga en cuenta que esto es Python 2.7, de ahí las declaraciones print.

5

método fácil :)

import sys 
from time import sleep 
import os 

#print("\033[y coordinate;[x coordinateH Hello") 
os.system('cls') 
sleep(0.2) 
print("\033[1;1H[]") 
sleep(0.2) 
print("\033[1;1H []") 
sleep(0.2) 
print("\033[1;1H []") 
sleep(0.2) 
print("\033[1;1H  []") 
sleep(0.2) 
print("\033[1;1H  []") 
sleep(0.2) 
print("\033[1;1H  []") 
sleep(0.2) 
print("\033[1;1H []") 
sleep(0.2) 
print("\033[1;1H []") 
sleep(0.2) 
print("\033[1;1H[]") 
sleep(0.2) 
0

Gracias por todas las respuestas útiles en chicos aquí. Necesitaba esto :)

Encontré la respuesta de nosklo particularmente útil, pero quería algo completamente contenido dentro de una función pasando el resultado deseado como parámetro. Además, realmente no necesitaba el temporizador, ya que quería que la impresión tuviera lugar después de un evento específico).

Esto es lo que hizo el truco para mí, espero que alguien le resulta útil:

import sys 

def replace_cmd_line(output): 
    """Replace the last command line output with the given output.""" 
    sys.stdout.write(output) 
    sys.stdout.flush() 
    sys.stdout.write('\r') 
    sys.stdout.flush() 
+0

Necesita solo una descarga() al final. No estoy seguro de que 'sys.stdout.write (output + '\ r')' sea mucho más rápido que dos llamadas a métodos (debido a la asignación de memoria para la cadena, copia, GC), por lo que mantenerlos separados probablemente sea correcto . –

1

La manera más fácil es utilizar dos \ r - una al principio y otra al final

for i in range(10000): 
    print('\r'+str(round(i*100/10000))+'% Complete\r'), 

se irá bastante rápido

+0

: -/El primer '\ r' se procesará 9999 veces en vano. Si no sabe dónde está su cursor, puede llamar 'print ('\ r')' * una vez * antes del bucle. –

Cuestiones relacionadas