Динамическая печать терминала с помощью python
Некоторые приложения, такие как hellanzb, имеют способ печати на терминал с появлением динамически обновляемых данных, вроде как top().
Какой лучший метод для python для этого? Я прочитал о регистрации и проклятиях, но не знаю, что использовать. Я создаю повторную реализацию вершины. Если у вас есть другие предложения, я им открыт.
Ответы
Ответ 1
Самый простой способ, если вам только нужно обновить одну строку (например, создать индикатор выполнения), - использовать '\r'
(возврат каретки) и 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)
Если вам нужен правильный интерфейс консоли, который поддерживает перемещение указателя и т.д., используйте модуль curses
из стандартной библиотеки:
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)
Очень полезно использовать функцию curses.wrapper
для вызова вашей основной функции, она позаботится о том, чтобы очистить терминал в случае ошибка, поэтому после этого она не будет в непригодном состоянии.
Если вы создаете более сложный интерфейс, вы можете создать несколько окон для разных частей экрана, текстовых полей ввода и поддержки мыши.
Ответ 2
Как уже говорилось в большинстве ответов, у вас действительно мало возможностей для Linux, но для использования ncurses
. Но что, если вы не в Linux, или хотите что-то более высокоуровневое для создания пользовательского интерфейса терминала?
Я лично нашел отсутствие современного кросс-платформенного терминального API в Python расстраивающим, поэтому написал asciimatics, чтобы решить эту проблему. Он не только дает вам простой кросс-платформенный API, он также предоставляет множество абстракций более высокого уровня для виджеты и анимации пользовательского интерфейса, которые можно было бы легко использовать для создания верхнего пользовательского интерфейса.
Ответ 3
Звучит как задание для curses
. Это наиболее часто используемая библиотека для компоновки и управления экраном в текстовом режиме. Python имеет очень хорошую поддержку проклятий, включая поддержку панелей:
Ответ 4
Когда я делаю это в сценариях оболочки в Unix, я обычно использую чистую программу. Вы можете использовать модуль подпроцесса Python для его выполнения. Это, по крайней мере, даст вам то, что вы ищете быстро.
Ответ 5
[[email protected] ~]$ ldd /usr/bin/top | grep curses
libncursesw.so.5 => /lib64/libncursesw.so.5 (0x0000003ae1400000)
curses
это.
Ответ 6
Я взломал этот script с помощью curses
. Это действительно специальное решение, которое я сделал для удовольствия. Он не поддерживает прокрутку, но я думаю, что это хорошая отправная точка, если вы хотите создать монитор живого обновления с несколькими строками на терминале.
https://gist.github.com/tpandit/b2bc4f434ee7f5fd890e095e79283aec
Ответ 7
Отправка вывода на терминал с помощью команды print() может выполняться без прокрутки, если вы используете атрибут "end".
Значение по умолчанию - end = '\n', которое является новой строкой.
Чтобы подавить прокрутку и перезаписать всю предыдущую строку, вы можете использовать escape RETURN, который равен '\ r'.
Если вы хотите только переписать последние четыре символа, вы можете использовать несколько обратных пространств.
print(value, "_of_", total, end='\r')
Примечание
Это работает для стандартного системного терминала. Терминальный эмулятор в некоторых инструментах, таких как IDLE, имеет ошибку, а "\ r" работает неправильно, выход просто конкатенируется с некоторым непечатаемым символом между ними.
БОНУСНАЯ ИНФОРМАЦИЯ ДЛЯ print()
В приведенном выше примере пространства на каждой стороне "из" предназначены для обеспечения пробела между моими значениями и словом "из". Однако разделитель по умолчанию print() является "(пробелом), поэтому мы заканчиваем пробелом между значением и подчеркиванием" _of_".
>> print (value, "_of_", total, end='\r')
8 _of_ 17
Атрибут sepparator, sep, может использоваться для установки символа между печатными элементами. В моем примере я изменю его на нулевую строку (''), чтобы мой результат соответствовал моим потребностям.
>> print (value, "_of_", total, sep='', end='\r')
8_of_17