più stampe sulla stessa riga in Python


229

Voglio eseguire uno script, che sostanzialmente mostra un output come questo:

Installing XXX...               [DONE]

Attualmente stampo Installing XXX...prima e poi stampo [DONE].

Tuttavia, ora voglio stampare Installing xxx...e [DONE]sulla stessa riga.

Qualche idea?



1
Le risposte a questa domanda non menzionano che a volte si desidera cancellare la linea, si veda: stackoverflow.com/questions/45263205
ideasman42

Risposte:


284

È possibile utilizzare l' printistruzione per farlo senza importare sys.

def install_xxx():
   print "Installing XXX...      ",

install_xxx()
print "[DONE]"

La virgola alla fine della printriga impedisce printdi emettere una nuova riga (si noti che ci sarà uno spazio extra alla fine dell'output).

La soluzione Python 3
Dato che quanto sopra non funziona in Python 3, puoi invece farlo (di nuovo, senza importare sys):

def install_xxx():
    print("Installing XXX...      ", end="", flush=True)

install_xxx()
print("[DONE]")

La funzione di stampa accetta un endparametro predefinito "\n". L'impostazione su una stringa vuota impedisce di emettere una nuova riga alla fine della riga.


1
Funziona perfettamente. Finora avevo visto solo soluzioni stdout. Davvero bello saperlo.
Prometeo,

5
Questo non funziona se hai entrambe le stampe e un'azione che richiede tempo nel mezzo (tutte nello stesso livello di funzione / rientro). Prima dell'inizio dell'azione, non viene emesso alcun output e al termine dell'output appare intero
Paddre,

2
Ciò è probabilmente più una funzione del buffer di output preformato dal sistema operativo per l'intero processo, che non è un problema specifico di Python. Consulta stackoverflow.com/questions/107705 per una soluzione specifica per Python.
multiple

13
Senza una nuova riga, probabilmente si desidera svuotare esplicitamente il buffer. Usa print("...", end="", flush=True)in Python 3, in Python 2 aggiungi una sys.stdout.flush()chiamata.
Martijn Pieters

7
in Python 3.x ti consigliamo di aggiungere un "\ r" per terminare per sostituire la riga stampata VS che si aggiunge alla fineprint("Progress: {}%".format(var), end="\r", flush=True)
John

103

Puoi semplicemente usare questo:

print 'something',
...
print ' else',

e l'output sarà

something else

non c'è bisogno di esagerare import sys. Prestare attenzione al simbolo della virgola alla fine.

Python 3+ print("some string", end=""); per rimuovere l'inserto newline alla fine. Leggi di più suhelp(print);


3
Nota che ci sono due spazi usando questo metodo
ethanjyx

1
Questa è la risposta più semplice ed efficiente.
gixxer,

Questo non funziona quando gli argomenti di stampa sono tra parentesi. Funziona: <print "ciao" ,; print ("hello")> ma questo non funziona <print ("hello",); print ("ciao")>
Mayank Jaiswal,

@MayankJaiswal Funziona con i genitori. print ('hello'),
drglove,

1
printla funzione ha una sintassi leggermente diversa in Python 2 VS 3.
boldnik

52

Dovresti usare backspace ' \ r ' o (' \ x08 ') char per tornare alla posizione precedente nell'output della console

Python 2+:

import time
import sys

def backspace(n):
    sys.stdout.write((b'\x08' * n).decode()) # use \x08 char to go back   

for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    sys.stdout.write(s)                     # just print
    sys.stdout.flush()                      # needed for flush when using \x08
    backspace(len(s))                       # back n chars    
    time.sleep(0.2)                         # sleep for 200ms

Python 3:

import time   

def backline():        
    print('\r', end='')                     # use '\r' to go back


for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    print(s, end='')                        # just print and flush
    backline()                              # back to the beginning of line    
    time.sleep(0.2)                         # sleep for 200ms

Questo codice verrà conteggiato dallo 0% al 100% su una riga. Il valore finale sarà:

> python test.py
100%

Ulteriori informazioni su flush in questo caso qui: Perché le istruzioni di stampa di Python che contengono argomenti 'end =' si comportano diversamente nei cicli while?


1
Per chiarire, sembra che il codice commentato in questo esempio sia per Python 2 e che le righe non commentate siano per Python 3.
Turtles Are Cute

1
le linee bouth funzioneranno bene in Python 3. Se usi '\ x08' come backspace devi svuotare il flusso di output - print ((b '\ x08' * n) .decode (), end = '', flush = Vero)
Vadim Zin4uk del

1
Il ritorno a
capo

43

Usa sys.stdout.write('Installing XXX... ')e sys.stdout.write('Done'). In questo modo, è necessario aggiungere manualmente la nuova riga "\n"se si desidera ricreare la funzionalità di stampa. Penso che potrebbe non essere necessario usare maledizioni solo per questo.


4
Personalmente preferisco questa soluzione a quella più votata perché funziona esattamente allo stesso modo su python2.xe python3.x senza dover fare affidamento su __future__importazioni o cose del genere.
mgilson

17

Nessuna delle risposte ha funzionato per me poiché si sono fermate tutte fino a quando non è stata trovata una nuova riga. Ho scritto un semplice aiuto:

def print_no_newline(string):
    import sys
    sys.stdout.write(string)
    sys.stdout.flush()

Per testarlo:

import time
print_no_newline('hello ')
# Simulate a long task
time.sleep(2)
print('world')

"ciao" verrà prima stampato e scaricato sullo schermo prima del sonno. Successivamente è possibile utilizzare la stampa standard.


1
Grazie! Esattamente quello di cui avevo bisogno alias .flush ()
MrNice


11

Più semplice:

Python 3

    print('\r' + 'something to be override', end='')

Significa che riporterà il cursore all'inizio, che stamperà qualcosa e finirà sulla stessa riga. Se in un ciclo inizierà a stampare nello stesso punto in cui inizia.


3
Freddo! Funziona anche in Windows.
Shital Shah,

2
Grazie per me funziona benissimo! Penso che print(’something to be override’, end=‘\r’)sia più semplice, però.
Tropilio,

9

Questo semplice esempio stampa 1-10 sulla stessa riga.

for i in range(1,11):
    print (i, end=" ")

9

La stampa ha un endargomento opzionale , è ciò che è stato stampato alla fine. L'impostazione predefinita è una nuova riga, ma è possibile cambiarla in stringa vuota. per esempioprint("hello world!", end="")


2
Questo è in Python 3. In Python 2 puoi semplicemente print 'something',. La virgola alla fine impedisce l'aggiunta di una nuova riga.
Arjoonn,

4

Se si desidera sovrascrivere la riga precedente (anziché aggiungerla continuamente), è possibile combinare \rcon print(),alla fine dell'istruzione di stampa. Per esempio,

from time import sleep

for i in xrange(0, 10):
    print("\r{0}".format(i)),
    sleep(.5)

print("...DONE!")

conterà da 0 a 9, sostituendo il vecchio numero nella console. La "...DONE!"stamperà sulla stessa linea come l'ultimo contatore, 9.

Nel tuo caso per l'OP, ciò consentirebbe alla console di visualizzare la percentuale di completamento dell'installazione come una "barra di avanzamento", in cui è possibile definire una posizione iniziale e finale del carattere e aggiornare gli indicatori intermedi.

print("Installing |XXXXXX              | 30%"),

4

Ecco una versione compatibile 2.7 derivata dalla versione 3.0 di @ Vadim-Zin4uk:

Python 2

import time

for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    print '{0}\r'.format(s),                # just print and flush

    time.sleep(0.2)

Del resto, la soluzione 3.0 fornita sembra un po 'gonfia. Ad esempio, il metodo backspace non utilizza l'argomento intero e probabilmente potrebbe essere eliminato del tutto.

Python 3

import time

for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    print('{0}\r'.format(s), end='')        # just print and flush

    time.sleep(0.2)                         # sleep for 200ms

Entrambi sono stati testati e funzionano.


2

Questo è un thread molto vecchio, ma ecco una risposta molto esaustiva e un codice di esempio.

\rè la rappresentazione in stringa di Carriage Return dal set di caratteri ASCII. È uguale a ottale 015[ chr(0o15)] o esadecimale 0d[ chr(0x0d)] o decimale 13[ chr(13)]. Vedere man asciiper una lettura noiosa. It ( \r) è una rappresentazione abbastanza portatile ed è abbastanza facile da leggere per le persone. Significa semplicemente riportare il carrello sulla macchina da scrivere fino all'inizio, senza far avanzare la carta. È la CRparte di ciò CRLFche significa ritorno a capo e avanzamento riga .

print()è una funzione in Python 3. In Python 2 (qualsiasi versione che ti interessa usare), printpuò essere forzata in una funzione importando la sua definizione dal __future__modulo. Il vantaggio della printfunzione è che è possibile specificare cosa stampare alla fine, ignorando il comportamento predefinito di \nstampare una nuova riga alla fine di ogni print()chiamata.

sys.stdout.flushdice a Python di svuotare l'output dell'output standard , che è dove si invia l'output a print()meno che non si specifichi diversamente. È inoltre possibile ottenere lo stesso comportamento eseguendo python -uo impostando la variabile di ambiente PYTHONUNBUFFERED=1, saltando in tal modo le chiamate import syse sys.stdout.flush(). L'importo che guadagni facendo questo è quasi esattamente zero e non è molto facile eseguire il debug se dimentichi convenientemente che devi fare quel passo prima che l'applicazione si comporti correttamente.

E un campione. Nota che funziona perfettamente in Python 2 o 3.

from __future__ import print_function

import sys
import time

ANS = 42
FACTORS = {n for n in range(1, ANS + 1) if ANS % n == 0}

for i in range(1, ANS + 1):
    if i in FACTORS:
        print('\r{0:d}'.format(i), end='')
        sys.stdout.flush()
        time.sleep(ANS / 100.0)
else:
    print()

Penso che la tua risposta sia più adatta a: stackoverflow.com/questions/45263205/…
Marc Cayuela Rafols,

2

print () ha un parametro incorporato "end" che è impostato di default su "\ n" Chiamare print ("Questa è l'America") in realtà sta chiamando print ("Questa è l'America", end = "\ n"). Un modo semplice per farlo è chiamare print ("This is America", end = "")


1

Nel caso in cui tu abbia pre-memorizzato i valori in un array, puoi chiamarli nel seguente formato:

for i in range(0,n):
       print arr[i],

1

Python aggiunge newline alla fine della stampa. Utilizzare end = '' per python3 per il metodo di stampa per aggiungere uno spazio anziché una nuova riga. per python2 usa la virgola alla fine dell'istruzione print.

print("Foo",end=' ')
print('Bar')

0

Ho trovato questo post di Quora , con questo esempio che ha funzionato per me (python 3), che era più vicino a quello di cui avevo bisogno (cioè cancellare l'intera riga precedente).

L'esempio che forniscono:

def clock():
   while True:
       print(datetime.now().strftime("%H:%M:%S"), end="\r")

Per stampare sulla stessa linea, come altri hanno suggerito, basta usare end=""


-2

Ho trovato questa soluzione e funziona su Python 2.7

# Working on Python 2.7 Linux

import time
import sys


def backspace(n):
    print('\r', end='')                     # use '\r' to go back


for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    sys.stdout.write(string)
    backspace(len(s))                       # back for n chars
    sys.stdout.flush()
    time.sleep(0.2)                         # sleep for 200ms

1
Questa printè sintassi errata per Python 2.7 e il codice non funziona anche con la sintassi corretta.
Cory Madden
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.