Na marginesie, upewnij się, że otrzymałeś odpowiedź, która może opróżnić całą linię, jeśli poprzednia linia jest dłuższa niż bieżąca.
Owoce
Odpowiedzi:
119
Jednym ze sposobów jest użycie znaku powrotu karetki ( '\r'), aby powrócić na początek wiersza bez przechodzenia do następnego wiersza:
for x in range(10):print'{0}\r'.format(x),print
Przecinek na końcu instrukcji print mówi mu, aby nie przechodził do następnego wiersza. Ostatnia instrukcja print przechodzi do następnego wiersza, więc znak zachęty nie nadpisze końcowego wyniku.
Aktualizacja
Teraz, gdy Python 2 to EOL, odpowiedź w Pythonie 3 ma większy sens. Dla Pythona 3.5 i wcześniejszych:
for x in range(10):print('{}\r'.format(x), end="")print()
W Pythonie 3.6 i nowszych f-stringi czytają lepiej:
To działa, ale nie rozumiem kilku części ... „{0}” i .format
ccwhite1
7
Zostało to wprowadzone w Pythonie 2.6 i (jak mi powiedziano) jest standardowym sposobem formatowania łańcuchów w Pythonie 3; %operator jest zalecane. Zasadniczo wszystkie ciągi mają teraz metodę formatowania . W tym przypadku {0}oznacza „pierwszy argument do format()” (liczenie zaczyna się od 0).
Mike DeSimone
Nie jest to opcja, jeśli musisz używać oprogramowania tylko dla systemu Windows i nie masz wystarczających umiejętności, aby uruchomić maszynę wirtualną.
Mike DeSimone
2
A jeśli chcesz być między terminalami, re.sub(r'\$<\d+>[/*]?', '', curses.tigetstr('el') or '')poda ci poprawny ciąg wymazywania do końca linii dla dowolnego terminala, który ma użytkownik. Pamiętaj, aby zainicjować cursescoś podobnego curses.setupterm(fd=sys.stdout.fileno())i użyć, sys.stdout.isatty()aby upewnić się, że dane wyjściowe nie są przekierowywane do pliku. Zobacz code.activestate.com/recipes/475116, aby zapoznać się z pełnym modułem Pythona z kontrolą kursora i obsługą kolorów.
Mike DeSimone
1
@PhilMacKay: Próbowałem tego w Pythonie na moim Macu: W [3]: print "Rzecz do usunięcia \ r",; time.sleep (1); print "-------------- \ r", -------------- Myślę, że twój problem dotyczy systemu Windows i jego różnych linii się kończy. Spróbuj tego: import curses; curses.setupterm(fd=sys.stdout.fileno()); print(hex(curses.tigetstr('cr')));Powinien wydrukować kody szesnastkowe sekwencji znaków, aby przejść na początek wiersza.
Mike DeSimone
107
Ponieważ znalazłem się tutaj przez Google, ale używam Pythona 3, oto jak to działałoby w Pythonie 3:
for x in range(10):print("Progress {:2.1%}".format(x /10), end="\r")
Próbowałem tego i w większości działa dobrze. Jedynym problemem jest to, że nie usuwa wcześniejszego wyjścia w tej linii, na przykład: jeśli twoja pierwsza pętla drukuje testingi druga pętla wydrukuje testwynik po drugim przebiegu nadal będzie testing- teraz widzę, że @ Nagasaki45 zwrócił na to uwagę
Eric Uldall
15
w notatniku ipython muszę zrobić:print("\r", message, end="")
grisaitis
1
To działa świetnie, nie usuwa linii, ale użycie wystarczającej ilości białych znaków w następującym wydruku załatwia sprawę (chociaż nie jest eleganckie). Jeden komentarz, który mógłbym dodać, to to, że nie działa to w konsoli debugowania VS Code, ale działa w terminalu.
PhilMacKay,
32
@Mike DeSimone odpowiedź prawdopodobnie będzie działać przez większość czasu. Ale...
for x in['abc',1]:print'{}\r'.format(x),->1bc
Dzieje się tak, ponieważ '\r'jedyny wraca na początek wiersza, ale nie czyści wyjścia.
EDYCJA: Lepsze rozwiązanie (niż moja stara propozycja poniżej)
Jeśli obsługa POSIX jest dla Ciebie wystarczająca, poniższe czynności wyczyściłyby bieżący wiersz i pozostawił kursor na jego początku:
import time
whileTrue:print("Hi ", end="\r")
time.sleep(1)print("Bob", end="\r")
time.sleep(1)
U mnie to zadziałało. end="\r"Część czyni go nadpisać poprzednią linię.
OSTRZEŻENIE!
Jeśli wydrukujesz hi, a następnie wydrukujesz za hellopomocą \r, otrzymasz, hilloponieważ wynik został napisany na poprzednich dwóch literach. Jeśli wydrukujesz hize spacjami (które nie pojawiają się tutaj), to wyjdzie hi. Aby to naprawić, wydrukuj spacje za pomocą \r.
To nie działa na mnie. Skopiowałem ten kod, ale wynik jest Hi BobHi BobHi BobHi BobHi Bob. Python 3.7.1
PaulMag
1
Ale odpowiedź Rubixreda zadziałała. Dziwne. Dla mnie wyglądają na tę samą metodę. Jedyną różnicą, jaką widzę, jest to, że \rjest na początku zamiast na końcu.
PaulMag
7
Nie mogłem uzyskać żadnego z rozwiązań na tej stronie do pracy z IPythonem , ale niewielka zmiana w rozwiązaniu @ Mike-Desimone załatwiła sprawę: zamiast kończyć wiersz znakiem powrotu karetki, rozpocznij wiersz od powrotu karetki:
for x in range(10):print'\r{0}'.format(x),
Ponadto to podejście nie wymaga drugiej instrukcji print.
for x in range(10):
time.sleep(0.5)# shows how its workingprint("\r {}".format(x), end="")
time.sleep (0.5) pokazuje, jak poprzedni wynik jest kasowany, a nowy wydruk jest drukowany "\ r". Kiedy jest na początku komunikatu drukowania, usunie poprzednie wyjście przed nowym wyjściem.
Przyjęta odpowiedź nie jest doskonała . Linia, która została wydrukowana jako pierwsza, pozostanie tam, a jeśli twój drugi wydruk nie pokryje całej nowej linii, skończysz ze śmieciowym tekstem.
Aby zilustrować problem, zapisz ten kod jako skrypt i uruchom go (lub po prostu spójrz):
import time
n =100for i in range(100):for j in range(100):print("Progress {:2.1%}".format(j /100), end="\r")
time.sleep(0.01)print("Progress {:2.1%}".format(i /100))
To, co działa dla mnie, to wyczyszczenie linii przed pozostawieniem trwałego wydruku. Zapraszam do dostosowania się do konkretnego problemu:
import time
ERASE_LINE ='\x1b[2K'# erase line command
n =100for i in range(100):for j in range(100):print("Progress {:2.1%}".format(j /100), end="\r")
time.sleep(0.01)print(ERASE_LINE +"Progress {:2.1%}".format(i /100))# clear the line first
Oto bardziej przejrzysta, bardziej „plug-and-play” wersja odpowiedzi @ Nagasaki45. W przeciwieństwie do wielu innych odpowiedzi tutaj, działa poprawnie ze sznurkami o różnych długościach. Osiąga to poprzez wyczyszczenie wiersza z taką samą liczbą spacji, jak długość ostatniego wydrukowanego wiersza. Działa również w systemie Windows.
def print_statusline(msg: str):
last_msg_length = len(print_statusline.last_msg)if hasattr(print_statusline,'last_msg')else0print(' '* last_msg_length, end='\r')print(msg, end='\r')
sys.stdout.flush()# Some say they needed this, I didn't.
print_statusline.last_msg = msg
Stosowanie
Po prostu użyj tego w ten sposób:
for msg in["Initializing...","Initialization successful!"]:
print_statusline(msg)
time.sleep(1)
Ten mały test pokazuje, że linie są usuwane prawidłowo, nawet przy różnych długościach:
for i in range(9,0,-1):
print_statusline("{}".format(i)* i)
time.sleep(0.5)
To świetne rozwiązanie, ponieważ elegancko czyści poprzedni wydruk do pełnej długości bez drukowania dowolnej liczby białych spacji (do czego wcześniej się uciekłem!). Dzięki
Toby Petty
2
Jestem trochę zaskoczony, że nikt nie używa znaku backspace. Oto jeden, który go używa.
import sys
import time
secs =1000whileTrue:
time.sleep(1)#wait for a full second to pass before assigning a second
secs +=1#acknowledge a second has passed
sys.stdout.write(str(secs))for i in range(len(str(secs))):
sys.stdout.write('\b')
upewnij się, że spłukujesz po użyciu tej metody, w przeciwnym razie nic nie zostanie wydrukowane na ekranie. sys.stdout.flush()
Gabriel Fair
2
(Python3) To właśnie zadziałało dla mnie. Jeśli użyjesz tylko \ 010, to pozostawi znaki, więc poprawiłem go trochę, aby upewnić się, że nadpisuje to, co tam było. Pozwala to również mieć coś przed pierwszym drukowanym elementem i usunąć tylko długość elementu.
print("Here are some strings: ", end="")
items =["abcd","abcdef","defqrs","lmnop","xyz"]for item in items:print(item, end="")for i in range(len(item)):# only moving back the length of the itemprint("\010 \010", end="")# the trick!
time.sleep(0.2)# so you can see what it's doing
import time
from pbar import update_progress_bar, print2
update_progress_bar(45,200)
time.sleep(1)
update_progress_bar(70,200)
time.sleep(1)
update_progress_bar(100,200)
time.sleep(1)
update_progress_bar(130,200)
time.sleep(1)
print2('some text that will re-place current progress bar')
time.sleep(1)
update_progress_bar(111,200)
time.sleep(1)print('\n')# without \n next line will be attached to the end of the progress barprint('built in print function that will push progress bar one line up')
time.sleep(1)
update_progress_bar(111,200)
time.sleep(1)
Nie jestem pewien, dlaczego ten kod działa, ale całkowicie usuwa oryginalny wiersz. Skompilowałem to na podstawie poprzednich odpowiedzi. Inne odpowiedzi po prostu przywróciłyby linię na początek, ale gdybyś miał później krótszą linię, wyglądałaby na pomieszaną, jakby hellozamieniła się w byelo.
import sys
#include ctypes if you're on Windowsimport ctypes
kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11),7)#end ctypesdef clearline(msg):
CURSOR_UP_ONE ='\033[K'
ERASE_LINE ='\x1b[2K'
sys.stdout.write(CURSOR_UP_ONE)
sys.stdout.write(ERASE_LINE+'\r')print(msg, end='\r')#example
ig_usernames =['beyonce','selenagomez']for name in ig_usernames:
clearline("SCRAPING COMPLETE: "+ name)
Wyjście - każda linia zostanie przepisana bez żadnego starego tekstu pokazującego:
SCRAPING COMPLETE: selenagomez
Następna linia (przepisana całkowicie w tej samej linii):
Odpowiedzi:
Jednym ze sposobów jest użycie znaku powrotu karetki (
'\r'
), aby powrócić na początek wiersza bez przechodzenia do następnego wiersza:Przecinek na końcu instrukcji print mówi mu, aby nie przechodził do następnego wiersza. Ostatnia instrukcja print przechodzi do następnego wiersza, więc znak zachęty nie nadpisze końcowego wyniku.
Aktualizacja
Teraz, gdy Python 2 to EOL, odpowiedź w Pythonie 3 ma większy sens. Dla Pythona 3.5 i wcześniejszych:
W Pythonie 3.6 i nowszych f-stringi czytają lepiej:
źródło
%
operator jest zalecane. Zasadniczo wszystkie ciągi mają teraz metodę formatowania . W tym przypadku{0}
oznacza „pierwszy argument doformat()
” (liczenie zaczyna się od 0).re.sub(r'\$<\d+>[/*]?', '', curses.tigetstr('el') or '')
poda ci poprawny ciąg wymazywania do końca linii dla dowolnego terminala, który ma użytkownik. Pamiętaj, aby zainicjowaćcurses
coś podobnegocurses.setupterm(fd=sys.stdout.fileno())
i użyć,sys.stdout.isatty()
aby upewnić się, że dane wyjściowe nie są przekierowywane do pliku. Zobacz code.activestate.com/recipes/475116, aby zapoznać się z pełnym modułem Pythona z kontrolą kursora i obsługą kolorów.import curses; curses.setupterm(fd=sys.stdout.fileno()); print(hex(curses.tigetstr('cr')));
Powinien wydrukować kody szesnastkowe sekwencji znaków, aby przejść na początek wiersza.Ponieważ znalazłem się tutaj przez Google, ale używam Pythona 3, oto jak to działałoby w Pythonie 3:
Powiązana odpowiedź tutaj: Jak mogę pominąć znak nowej linii po instrukcji print?
źródło
testing
i druga pętla wydrukujetest
wynik po drugim przebiegu nadal będzietesting
- teraz widzę, że @ Nagasaki45 zwrócił na to uwagęprint("\r", message, end="")
@Mike DeSimone odpowiedź prawdopodobnie będzie działać przez większość czasu. Ale...
Dzieje się tak, ponieważ
'\r'
jedyny wraca na początek wiersza, ale nie czyści wyjścia.EDYCJA: Lepsze rozwiązanie (niż moja stara propozycja poniżej)
Jeśli obsługa POSIX jest dla Ciebie wystarczająca, poniższe czynności wyczyściłyby bieżący wiersz i pozostawił kursor na jego początku:
Używa kodu ucieczki ANSI, aby wyczyścić linię terminala. Więcej informacji można znaleźć na Wikipedii oraz w tym wspaniałym wykładzie .
Stara odpowiedź
(Niezbyt dobre) rozwiązanie, które znalazłem, wygląda następująco:
Zaletą jest to, że będzie działać również w systemie Windows.
źródło
Miałem to samo pytanie przed odwiedzeniem tego wątku. U mnie sys.stdout.write działał tylko wtedy, gdy prawidłowo opróżnię bufor tj
Bez opróżniania wynik jest drukowany tylko na końcu skryptu
źródło
stringvar.ljust(10,' ')
w przypadku łańcuchów o zmiennej długości.Pomiń znak nowej linii i drukuj
\r
.lub napisz na stdout:
źródło
Spróbuj tego:
U mnie to zadziałało.
end="\r"
Część czyni go nadpisać poprzednią linię.OSTRZEŻENIE!
Jeśli wydrukujesz
hi
, a następnie wydrukujesz zahello
pomocą\r
, otrzymasz,hillo
ponieważ wynik został napisany na poprzednich dwóch literach. Jeśli wydrukujeszhi
ze spacjami (które nie pojawiają się tutaj), to wyjdziehi
. Aby to naprawić, wydrukuj spacje za pomocą\r
.źródło
Hi BobHi BobHi BobHi BobHi Bob
. Python 3.7.1\r
jest na początku zamiast na końcu.Nie mogłem uzyskać żadnego z rozwiązań na tej stronie do pracy z IPythonem , ale niewielka zmiana w rozwiązaniu @ Mike-Desimone załatwiła sprawę: zamiast kończyć wiersz znakiem powrotu karetki, rozpocznij wiersz od powrotu karetki:
Ponadto to podejście nie wymaga drugiej instrukcji print.
źródło
time.sleep (0.5) pokazuje, jak poprzedni wynik jest kasowany, a nowy wydruk jest drukowany "\ r". Kiedy jest na początku komunikatu drukowania, usunie poprzednie wyjście przed nowym wyjściem.
źródło
Działa to w systemie Windows i Pythonie 3.6
źródło
Przyjęta odpowiedź nie jest doskonała . Linia, która została wydrukowana jako pierwsza, pozostanie tam, a jeśli twój drugi wydruk nie pokryje całej nowej linii, skończysz ze śmieciowym tekstem.
Aby zilustrować problem, zapisz ten kod jako skrypt i uruchom go (lub po prostu spójrz):
Wynik będzie wyglądał mniej więcej tak:
To, co działa dla mnie, to wyczyszczenie linii przed pozostawieniem trwałego wydruku. Zapraszam do dostosowania się do konkretnego problemu:
A teraz drukuje zgodnie z oczekiwaniami:
źródło
Oto bardziej przejrzysta, bardziej „plug-and-play” wersja odpowiedzi @ Nagasaki45. W przeciwieństwie do wielu innych odpowiedzi tutaj, działa poprawnie ze sznurkami o różnych długościach. Osiąga to poprzez wyczyszczenie wiersza z taką samą liczbą spacji, jak długość ostatniego wydrukowanego wiersza. Działa również w systemie Windows.
Stosowanie
Po prostu użyj tego w ten sposób:
Ten mały test pokazuje, że linie są usuwane prawidłowo, nawet przy różnych długościach:
źródło
Jestem trochę zaskoczony, że nikt nie używa znaku backspace. Oto jeden, który go używa.
źródło
sys.stdout.flush()
(Python3) To właśnie zadziałało dla mnie. Jeśli użyjesz tylko \ 010, to pozostawi znaki, więc poprawiłem go trochę, aby upewnić się, że nadpisuje to, co tam było. Pozwala to również mieć coś przed pierwszym drukowanym elementem i usunąć tylko długość elementu.
źródło
Jeszcze jedna odpowiedź oparta na wcześniejszych odpowiedziach.
Zawartość pbar.py: import sys, shutil, datetime
Wykorzystanie skryptu:
źródło
Oto moje rozwiązanie! Windows 10, Python 3.7.1
Nie jestem pewien, dlaczego ten kod działa, ale całkowicie usuwa oryginalny wiersz. Skompilowałem to na podstawie poprzednich odpowiedzi. Inne odpowiedzi po prostu przywróciłyby linię na początek, ale gdybyś miał później krótszą linię, wyglądałaby na pomieszaną, jakby
hello
zamieniła się wbyelo
.Wyjście - każda linia zostanie przepisana bez żadnego starego tekstu pokazującego:
Następna linia (przepisana całkowicie w tej samej linii):
źródło
Lepiej jest nadpisać całą linię, w przeciwnym razie nowa linia będzie mieszać się ze starymi, jeśli nowa linia będzie krótsza.
Musiał użyć
columns - 1
w systemie Windows.źródło