wiele wydruków w tej samej linii w Pythonie

229

Chcę uruchomić skrypt, który w zasadzie pokazuje takie dane wyjściowe:

Installing XXX...               [DONE]

Obecnie drukuję Installing XXX...najpierw, a następnie drukuję [DONE].

Jednak teraz chcę drukować Installing xxx...i [DONE]na tej samej linii.

Jakieś pomysły?

użytkownik697108
źródło
1
Odpowiedzi na to pytanie nie wspominają, że czasami chcesz wyczyścić linię, patrz: stackoverflow.com/questions/45263205
ideasman42

Odpowiedzi:

284

Możesz użyć printinstrukcji, aby to zrobić bez importowania sys.

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

install_xxx()
print "[DONE]"

Przecinek na końcu printwiersza uniemożliwia printwydanie nowego wiersza (należy pamiętać, że na końcu danych wyjściowych będzie dodatkowe miejsce).

Rozwiązanie Python 3
Ponieważ powyższe nie działa w Python 3, możesz to zrobić zamiast tego (ponownie, bez importowania sys):

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

install_xxx()
print("[DONE]")

Funkcja drukowania akceptuje endparametr domyślnie ustawiony na "\n". Ustawienie go na pusty ciąg zapobiega wydaniu nowego wiersza na końcu wiersza.

wiele interfejsów
źródło
1
Działa idealnie. Dotychczas widziałem tylko standardowe rozwiązania. Naprawdę dobrze to wiedzieć.
Prometeusz
5
To nie działa, jeśli masz zarówno wydruki, jak i czasochłonne działanie pomiędzy nimi (wszystkie na tym samym poziomie funkcji / wcięcia). Przed rozpoczęciem akcji w ogóle nie ma żadnych wyników, a po jej zakończeniu pojawia się jako całość
Paddre
2
Prawdopodobnie jest to raczej funkcja buforowania danych wyjściowych utworzona przez system operacyjny dla całego procesu, co nie jest problemem specyficznym dla Pythona. Zobacz stackoverflow.com/questions/107705, aby uzyskać obejście specyficzne dla Pythona.
wiele
13
Bez znaku nowej linii prawdopodobnie chcesz wyczyścić bufor. Użyj print("...", end="", flush=True)w Python 3, w Python 2 dodaj sys.stdout.flush()połączenie.
Martijn Pieters
7
W Pythonie 3.x będziesz chciał dodać „\ r”, aby zakończyć zastąpić wydrukowany wiersz VS dołączanie do końca toprint("Progress: {}%".format(var), end="\r", flush=True)
John
103

Możesz po prostu użyć tego:

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

i wyjście będzie

something else

nie trzeba przesadzać import sys. Zwróć uwagę na symbol przecinka na końcu.

Python 3+, print("some string", end=""); aby usunąć wstawkę nowej linii na końcu. Czytaj dalej przezhelp(print);

boldnik
źródło
3
Zauważ, że przy użyciu tej metody są dwie spacje
ethanjyx,
1
To najprostsza i najskuteczniejsza odpowiedź.
gixxer
To nie działa, gdy argumenty print są w nawiasach. Działa to: <print "hello" ,; print („hello”)> ale to nie działa <print („hello”,); drukuj („cześć”)>
Mayank Jaiswal
@MayankJaiswal To działa z parens. print ('hello'),
drglove
1
printfunkcja ma nieco inną składnię w pythonie 2 VS 3.
boldnik
52

Powinieneś użyć znaku cofania „ \ r ” lub („ \ x08 ”) char, aby wrócić do poprzedniej pozycji w wynikach konsoli

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

Ten kod będzie liczył od 0% do 100% w jednej linii. Ostateczna wartość będzie wynosić:

> python test.py
100%

Dodatkowe informacje o opróżnianiu w tym przypadku tutaj: Dlaczego instrukcje drukowania python zawierające argumenty „end =” zachowują się inaczej w pętlach while?

Vadim Zin4uk
źródło
1
Aby to wyjaśnić, wygląda na to, że skomentowany kod w tym przykładzie dotyczy Pythona 2, a wiersze bez komentarza dotyczą Pythona 3.
Turtles Are Cute
1
linie bouth będą działać poprawnie w Pythonie 3. Jeśli użyjesz „\ x08” jako backspace, musisz opróżnić strumień wyjściowy - print ((b '\ x08' * n) .decode (), end = '', flush = Prawda)
Vadim Zin4uk
1
Znak powrotu karetki wraca na początek linii, więc „* n” nie jest konieczne
bjnortier
43

Użyj sys.stdout.write('Installing XXX... ')i sys.stdout.write('Done'). W ten sposób musisz ręcznie dodać nowy wiersz, "\n"jeśli chcesz odtworzyć funkcję drukowania. Myślę, że używanie do tego przekleństw może być niepotrzebne.

ferostar
źródło
4
Osobiście wolę to rozwiązanie od wyżej głosowanego, ponieważ działa dokładnie tak samo na python2.x i python3.x, bez konieczności polegania na __future__importach lub czymkolwiek podobnym.
mgilson
17

Żadna z odpowiedzi nie działała dla mnie, ponieważ wszystkie zostały wstrzymane, dopóki nie napotkano nowej linii. Napisałem prostego pomocnika:

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

Aby to przetestować:

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

„hello” wydrukuje najpierw i zasypie ekran przed snem. Następnie możesz użyć standardowego wydruku.

hyprnick
źródło
1
Dziękuję Ci! Dokładnie to, czego potrzebowałem aka .flush ()
MrNice,
11

Najprostszy:

Python 3

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

Oznacza to, że cofnie kursor do początku, niż wydrukuje coś i zakończy się w tym samym wierszu. Jeśli w pętli rozpocznie drukowanie w tym samym miejscu, w którym zaczyna.

Sunfloro
źródło
3
Chłodny! Działa również w systemie Windows.
Shital Shah
2
Dzięki, to działa dobrze dla mnie! Myślę jednak, że print(’something to be override’, end=‘\r’)jest to prostsze.
Tropilio,
9

Ten prosty przykład wydrukuje 1-10 w tym samym wierszu.

for i in range(1,11):
    print (i, end=" ")
Umali Leonard
źródło
9

Drukuj ma opcjonalny endargument, to jest to, co wydrukowano na końcu. Domyślnie jest to nowy wiersz, ale możesz go zmienić na pusty ciąg. na przykładprint("hello world!", end="")

TulkinRB
źródło
2
To jest w python 3. W python 2 możesz po prostu print 'something',. Przecinek na końcu zapobiega dodaniu nowej linii.
arjoonn
4

Jeśli chcesz zastąpić poprzednią linię (zamiast ciągłego dodawania do niej), możesz połączyć ją \rz print(),na końcu instrukcji print. Na przykład,

from time import sleep

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

print("...DONE!")

będzie liczyć od 0 do 9, zastępując stary numer w konsoli. "...DONE!"Zostaną wydrukowane na tej samej linii co ostatni licznik, 9.

W twoim przypadku dla OP, pozwoliłoby to konsoli wyświetlić procent ukończenia instalacji jako „pasek postępu”, w którym możesz zdefiniować początkową i końcową pozycję znaku i zaktualizować znaczniki pomiędzy nimi.

print("Installing |XXXXXX              | 30%"),
Brian Bunker
źródło
4

Oto wersja zgodna z wersją 2.7 pochodząca z wersji 3.0 autorstwa @ 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)

Jeśli o to chodzi, dostarczone rozwiązanie 3.0 wygląda na nieco rozdęte. Na przykład metoda backspace nie korzysta z argumentu liczby całkowitej i prawdopodobnie mogłaby zostać całkowicie wyeliminowana.

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

Oba zostały przetestowane i działają.

Dannid
źródło
2

To jest bardzo stary wątek, ale tutaj jest bardzo dokładna odpowiedź i przykładowy kod.

\rto ciąg znaków reprezentujący powrót karetki z zestawu znaków ASCII. Jest taki sam jak ósemkowy 015[ chr(0o15)] lub szesnastkowy 0d[ chr(0x0d)] lub dziesiętny 13[ chr(13)]. Zobacz man asciinudne czytanie. Jest \rto dość przenośna reprezentacja i jest łatwa do odczytania przez ludzi. Po prostu oznacza to przesunięcie karetki na maszynie do pisania do samego początku bez przesuwania papieru. Jest to CRczęść, CRLFktóra oznacza powrót karetki i przesunięcie linii .

print()jest funkcją w Pythonie 3. W Pythonie 2 (dowolna wersja, z której chciałbyś skorzystać) printmożesz zostać zmuszony do funkcji poprzez zaimportowanie jej definicji z __future__modułu. Zaletą tej printfunkcji jest to, że możesz określić, co ma być drukowane na końcu, zastępując domyślne zachowanie \ndrukowania nowego wiersza na końcu każdego print()wywołania.

sys.stdout.flushmówi Pythonowi, aby wyczyścił wyjście standardowego wyjścia , czyli tam, gdzie wysyłasz wyjście, print()chyba że określono inaczej. Możesz także uzyskać to samo zachowanie, uruchamiając python -ulub ustawiając zmienną środowiskową PYTHONUNBUFFERED=1, pomijając w ten sposób wywołania import sysi sys.stdout.flush(). Kwota, którą zyskasz, robiąc to, jest prawie dokładnie zerowa i nie jest bardzo łatwa do debugowania, jeśli wygodnie zapomnisz, że musisz zrobić ten krok, zanim aplikacja zachowa się poprawnie.

I próbka. Zauważ, że działa to doskonale w Pythonie 2 lub 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
źródło
Myślę, że twoja odpowiedź jest bardziej odpowiednia dla: stackoverflow.com/questions/45263205/…
Marc Cayuela Rafols
2

print () ma wbudowany parametr „end”, który jest domyślnie ustawiony na „\ n” Wywołanie print („To jest Ameryka”) tak naprawdę wywołuje print („To jest Ameryka”, end = „\ n”). Łatwy sposób to wywołać print („This is America”, end = „”)

Miles Mbo
źródło
1

Na wypadek, gdybyś wcześniej zapisał wartości w tablicy, możesz wywołać je w następującym formacie:

for i in range(0,n):
       print arr[i],
k20392
źródło
1

Python dołącza znak nowej linii jako koniec drukowania. Użyj end = '' dla python3 dla metody drukowania, aby dodać spację zamiast nowego wiersza. dla python2 użyj przecinka na końcu instrukcji print.

print("Foo",end=' ')
print('Bar')
MrKulli
źródło
0

Znalazłem ten post Quora , z tym przykładem, który działał dla mnie (python 3), który był bliższy temu, do czego go potrzebowałem (tj. Usunięciu całej poprzedniej linii).

Podany przykład:

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

Do drukowania tego samego wiersza, jak sugerowali inni, wystarczy użyć end=""

Mircea
źródło
-2

Znalazłem to rozwiązanie i działa ono w Pythonie 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
źródło
1
To printjest niepoprawna składnia dla Pythona 2.7, a kod nie działa nawet z poprawną składnią.
Cory Madden,