plusieurs impressions sur la même ligne en Python

229

Je veux exécuter un script, qui affiche essentiellement une sortie comme celle-ci:

Installing XXX...               [DONE]

Actuellement, j'imprime d' Installing XXX...abord, puis j'imprime [DONE].

Cependant, je veux maintenant imprimer Installing xxx...et [DONE]sur la même ligne.

Des idées?

user697108
la source
1
Copie
Cees Timmerman
1
Les réponses à cette question ne mentionnent pas que parfois vous voulez effacer la ligne, voir: stackoverflow.com/questions/45263205
ideasman42

Réponses:

284

Vous pouvez utiliser l' printinstruction pour le faire sans importer sys.

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

install_xxx()
print "[DONE]"

La virgule à la fin de la printligne empêche printd'émettre une nouvelle ligne (vous devez noter qu'il y aura un espace supplémentaire à la fin de la sortie).

La solution Python 3
Étant donné que ce qui précède ne fonctionne pas dans Python 3, vous pouvez le faire à la place (encore une fois, sans importer sys):

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

install_xxx()
print("[DONE]")

La fonction d'impression accepte un endparamètre par défaut "\n". Le définir sur une chaîne vide l'empêche d'émettre une nouvelle ligne à la fin de la ligne.

plusieurs interfaces
la source
1
Cela fonctionne parfaitement. Jusqu'à présent, je n'avais vu que des solutions standard. Vraiment bien de le savoir.
Prometheus
5
Cela ne fonctionne pas si vous avez à la fois des impressions et une action longue (toutes au même niveau de fonction / indentation). Avant le début de l'action, il n'y a pas de sortie du tout et une fois terminée, la sortie apparaît comme entière
Paddre
2
C'est probablement plus une fonction de la mise en mémoire tampon de sortie préformée par le système d'exploitation pour le processus dans son ensemble, ce qui n'est pas un problème spécifique à Python. Voir stackoverflow.com/questions/107705 pour une solution de contournement spécifique à python.
multiples
13
Sans nouvelle ligne, vous souhaiterez probablement vider explicitement le tampon. Utilisation print("...", end="", flush=True)en Python 3, en Python 2 ajoutez un sys.stdout.flush()appel.
Martijn Pieters
7
en python 3.x, vous voudrez ajouter un "\ r" à la fin pour remplacer la ligne imprimée VS qui s'ajoute à la finprint("Progress: {}%".format(var), end="\r", flush=True)
John
103

Vous pouvez simplement utiliser ceci:

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

et la sortie sera

something else

pas besoin de surpasser par import sys. Faites attention au symbole de virgule à la fin.

Python 3+ print("some string", end=""); pour supprimer l'insertion de nouvelle ligne à la fin. Lire la suite parhelp(print);

boldnik
la source
3
Notez qu'il y a deux espaces en utilisant cette méthode
ethanjyx
1
C'est la réponse la plus simple et la plus efficace.
gixxer
Cela ne fonctionne pas lorsque les arguments d'impression sont entre parenthèses. Cela fonctionne: <print "hello" ,; print ("bonjour")> mais cela ne fonctionne pas <print ("bonjour",); imprimer ("bonjour")>
Mayank Jaiswal
@MayankJaiswal Cela fonctionne avec les parens. print ('hello'),
drglove
1
printLa fonction a une syntaxe légèrement différente dans Python 2 VS 3.
boldnik
52

Vous devez utiliser le retour arrière ' \ r ' ou (' \ x08 ') pour revenir à la position précédente dans la sortie de la 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

Ce code comptera de 0% à 100% sur une seule ligne. La valeur finale sera:

> python test.py
100%

Des informations supplémentaires sur flush dans ce cas ici: Pourquoi les instructions d'impression python qui contiennent des arguments 'end =' se comportent-elles différemment dans les boucles while?

Vadim Zin4uk
la source
1
Pour clarifier, il semble que le code commenté dans cet exemple soit pour Python 2, et les lignes non commentées sont pour Python 3.
Turtles Are Cute
1
les lignes bouth fonctionneront très bien dans Python 3. Si vous utilisez '\ x08' comme retour arrière, vous devez vider le flux de sortie - print ((b '\ x08' * n) .decode (), end = '', flush = Vrai)
Vadim Zin4uk
1
Le retour chariot '\ r' remonte au début de la ligne, donc le '* n' est inutile
bjnortier
43

Utilisez sys.stdout.write('Installing XXX... ')et sys.stdout.write('Done'). De cette façon, vous devez ajouter la nouvelle ligne à la main "\n"si vous souhaitez recréer la fonctionnalité d'impression. Je pense qu'il pourrait être inutile d'utiliser des malédictions juste pour cela.

ferostar
la source
4
Personnellement, je préfère cette solution à la plus élevée, car elle fonctionne exactement de la même manière sur python2.x et python3.x sans avoir besoin de s'appuyer sur les __future__importations ou quelque chose comme ça.
mgilson
17

Aucune des réponses n'a fonctionné pour moi car elles se sont toutes arrêtées jusqu'à ce qu'une nouvelle ligne soit rencontrée. J'ai écrit une aide simple:

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

Pour le tester:

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

"bonjour" imprimera d'abord et affleurera à l'écran avant le sommeil. Après cela, vous pouvez utiliser l'impression standard.

hyprnick
la source
1
Je vous remercie! Exactement ce dont j'avais besoin aka .flush ()
MrNice
11

Le plus simple:

Python 3

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

Cela signifie qu'il ramènera le curseur au début, qu'il imprimera quelque chose et se terminera sur la même ligne. S'il est en boucle, l'impression commencera au même endroit qu'il commence.

Sunfloro
la source
3
Cool! Fonctionne également sous Windows.
Shital Shah
2
Merci, cela fonctionne bien pour moi! Je pense que print(’something to be override’, end=‘\r’)c'est plus simple, cependant.
Tropilio
9

Cet exemple simple imprimera 1-10 sur la même ligne.

for i in range(1,11):
    print (i, end=" ")
Umali Leonard
la source
9

Print a un endargument optionnel , c'est ce qui est imprimé à la fin. La valeur par défaut est une nouvelle ligne, mais vous pouvez la remplacer par une chaîne vide. par exempleprint("hello world!", end="")

TulkinRB
la source
2
C'est en python 3. En python 2, vous pouvez simplement print 'something',. La virgule à la fin empêche l'ajout d'une nouvelle ligne.
arjoonn
4

Si vous souhaitez remplacer la ligne précédente (plutôt que d'y ajouter continuellement), vous pouvez combiner \ravec print(),à la fin de l'instruction d'impression. Par exemple,

from time import sleep

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

print("...DONE!")

comptera de 0 à 9, remplaçant l'ancien numéro dans la console. Le "...DONE!"sera imprimé sur la même ligne que le dernier compteur, 9.

Dans votre cas pour l'OP, cela permettrait à la console d'afficher le pourcentage d'achèvement de l'installation sous forme de "barre de progression", où vous pouvez définir une position de début et de fin de caractère et mettre à jour les marqueurs entre les deux.

print("Installing |XXXXXX              | 30%"),
Brian Bunker
la source
4

Voici une version compatible 2.7 dérivée de la version 3.0 de @ 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)

D'ailleurs, la solution 3.0 fournie semble un peu gonflée. Par exemple, la méthode de retour arrière n'utilise pas l'argument entier et pourrait probablement être complètement supprimée.

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

Les deux ont été testés et fonctionnent.

Dannid
la source
2

Il s'agit d'un fil très ancien, mais voici une réponse très complète et un exemple de code.

\rest la représentation sous forme de chaîne du retour chariot à partir du jeu de caractères ASCII. C'est la même chose que octal 015[ chr(0o15)] ou hexidécimal 0d[ chr(0x0d)] ou décimal 13[ chr(13)]. Voir man asciipour une lecture ennuyeuse. C'est ( \r) une représentation assez portable et assez facile à lire pour les gens. Cela signifie très simplement de déplacer le chariot sur la machine à écrire jusqu'au début sans faire avancer le papier. C'est la CRpartie CRLFqui signifie retour chariot et saut de ligne .

print()est une fonction en Python 3. En Python 2 (toute version que vous seriez intéressé à utiliser), printpeut être forcée dans une fonction en important sa définition depuis le __future__module. L'avantage de la printfonction est que vous pouvez spécifier ce qu'il faut imprimer à la fin, en remplaçant le comportement par défaut de \npour imprimer une nouvelle ligne à la fin de chaque print()appel.

sys.stdout.flushindique à Python de vider la sortie de la sortie standard , où vous envoyez la sortie, print()sauf indication contraire. Vous pouvez également obtenir le même comportement en exécutant avec python -uou en définissant la variable d'environnement PYTHONUNBUFFERED=1, ignorant ainsi les appels import syset sys.stdout.flush(). Le montant que vous gagnez en faisant cela est presque exactement nul et n'est pas très facile à déboguer si vous oubliez commodément que vous devez effectuer cette étape avant que votre application se comporte correctement.

Et un échantillon. Notez que cela fonctionne parfaitement en Python 2 ou 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()
Chris Cosby
la source
Je pense que votre réponse convient mieux à: stackoverflow.com/questions/45263205/…
Marc Cayuela Rafols
2

print () a un paramètre intégré "end" qui est par défaut défini sur "\ n" L'appel à print ("This is America") appelle en fait print ("This is America", end = "\ n"). Un moyen simple consiste à appeler print ("This is America", end = "")

Miles Mbo
la source
1

Juste au cas où vous auriez pré-stocké les valeurs dans un tableau, vous pouvez les appeler au format suivant:

for i in range(0,n):
       print arr[i],
k20392
la source
1

Python ajoute la nouvelle ligne comme fin à l'impression. Utilisez end = '' pour python3 pour la méthode d'impression pour ajouter un espace au lieu d'une nouvelle ligne. pour python2, utilisez une virgule à la fin de l'instruction print.

print("Foo",end=' ')
print('Bar')
MrKulli
la source
0

J'ai trouvé ce post Quora , avec cet exemple qui a fonctionné pour moi (python 3), qui était plus proche de ce dont j'avais besoin (c'est-à-dire en effaçant toute la ligne précédente).

L'exemple qu'ils fournissent:

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

Pour imprimer le sur la même ligne, comme d'autres l'ont suggéré, utilisez simplement end=""

Mircea
la source
-2

J'ai trouvé cette solution, et cela fonctionne sur 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
Luis Silva
la source
1
C'est printune syntaxe incorrecte pour Python 2.7 et le code ne fonctionne pas même avec une syntaxe correcte.
Cory Madden