Dynamiczne drukowanie terminali w Pythonie
Niektóre aplikacje jak hellanzb mają sposób drukowania do terminala z wyglądem dynamicznie odświeżających danych, jak top ().
Jaka jest najlepsza metoda w Pythonie? Czytałem o logowaniu i przekleństwach, ale nie wiem, czego użyć. Tworzę reimplementację top. Jeśli macie jakieś inne sugestie, również jestem na nie otwarty.
7 answers
Najprostszym sposobem, jeśli potrzebujesz tylko zaktualizować pojedynczą linię (na przykład tworząc pasek postępu), jest użycie '\r'
(powrót karetki) i sys.stdout
:
import sys
import time
for i in range(10):
sys.stdout.write("\r{0}>".format("="*i))
sys.stdout.flush()
time.sleep(0.5)
Jeśli potrzebujesz odpowiedniego interfejsu konsoli, który obsługuje Przesuwanie wskaźnika itp., użyj curses
Moduł z biblioteki standardowej:
import time
import curses
def pbar(window):
for i in range(10):
window.addstr(10, 10, "[" + ("=" * i) + ">" + (" " * (10 - i )) + "]")
window.refresh()
time.sleep(0.5)
curses.wrapper(pbar)
Jest wysoce wskazane, aby użyć curses.wrapper
funkcja aby wywołać główną funkcję, zajmie się czyszczeniem terminala w przypadku błędu, więc nie będzie w stan później bezużyteczny.
Jeśli utworzysz bardziej złożony interfejs użytkownika, możesz utworzyć wiele okien dla różnych części ekranu, pól wprowadzania tekstu i obsługi myszy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-23 11:31:21
Jak już większość odpowiedzi stwierdziła, na Linuksie naprawdę niewiele jest opcji poza używaniem ncurses
. Ale co, jeśli nie jesteś na Linuksie lub chcesz czegoś bardziej wysokiego poziomu do tworzenia interfejsu terminala?
Osobiście uważam, że brak nowoczesnego, wieloplatformowego terminala API w Pythonie jest frustrujący, więc napisałem asciimatics , aby rozwiązać ten problem. Nie tylko daje proste wieloplatformowe API , ale także zapewnia wiele abstrakcji wyższego poziomu dla UI widżety i animacje , które można łatwo wykorzystać do stworzenia interfejsu przypominającego górę.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-08 22:12:25
Brzmi jak praca dla curses
. Jest to najczęściej używana biblioteka do układania i zarządzania ekranem w trybie tekstowym. Python ma bardzo dobre wsparcie dla curses, w tym wsparcie dla paneli:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-23 06:51:57
Zhakowałem ten skrypt używając curses
. To naprawdę rozwiązanie ad-hoc zrobiłem dla Zabawy. Nie obsługuje przewijania, ale myślę, że jest to dobry punkt wyjścia, jeśli chcesz zbudować monitor aktualizacji na żywo z wieloma wierszami na terminalu.
Https://gist.github.com/tpandit/b2bc4f434ee7f5fd890e095e79283aec
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-08 19:31:14
Kiedy robię to w skryptach powłoki na Uniksie, zwykle używam tylko programu clear. Możesz użyć modułu podprocesu Pythona, aby go wykonać. Przynajmniej szybko dostaniesz to, czego szukasz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-23 06:47:33
[ignacio@localhost ~]$ ldd /usr/bin/top | grep curses
libncursesw.so.5 => /lib64/libncursesw.so.5 (0x0000003ae1400000)
curses
tak.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-23 06:48:40
Wysyłanie wyjścia do terminala za pomocą polecenia print() może być wykonane bez przewijania, jeśli użyjesz atrybutu "end".
Wartością domyślną jest end= '\N', czyli nowa linia.
Aby wyłączyć przewijanie i nadpisać całą poprzednią linię, możesz użyć ucieczki powrotu, która jest '\r'.
Jeśli chcesz przepisać tylko cztery ostatnie znaki, możesz użyć kilku spacji.
print(value, "_of_", total, end='\r')
Uwaga Działa to dla standardowego terminala systemowego. Terminal emulator w niektórych narzędziach, takich jak IDLE ma błąd i '\R' nie działa poprawnie, wyjście jest po prostu połączone z jakimś niedrukowalnym znakiem pomiędzy.
Informacje dodatkowe dla print () W powyższym przykładzie spacje po każdej stronie "of "mają na celu zapewnienie białej przestrzeni między moimi wartościami a słowem"of". Jednak domyślnym separatorem print () jest "" (spacja), więc kończymy z białą spacją między wartością a podkreśleniem "_of_".
>> print (value, "_of_", total, end='\r')
8 _of_ 17
Atrybut sepparator, sep, może być używany do ustawiania znaków pomiędzy drukowanymi elementami. W moim przykładzie zmienię go na null string ( " ), aby moje wyjście odpowiadało moim potrzebom.
>> print (value, "_of_", total, sep='', end='\r')
8_of_17
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-29 17:33:14