Реагировать на ключевые события, уже читая со стандартного ввода в Python - PullRequest
1 голос
/ 01 ноября 2011

Настройка

Я играл со скриптом, чтобы передать tail -f и выделить определенные ключевые слова. Не большой проект, но кое-что, что я нахожу полезным.

Прямо сейчас основной цикл в основном:

...
line = True
while line:
    line = sys.stdin.readline()
    sys.stdout.write(highlight(line))
...

Я хотел бы прослушать определенные нажатия клавиш во время этого цикла, чтобы напечатать строку маркера в журнале. Обнаруженный мной метод, который выглядит так, как будто он будет работать для получения нажатия клавиш, описан в http://code.activestate.com/recipes/134892/, но он читает по одному символу за раз из stdin, который не будет работать, когда мой основной цикл читает целые строки из это.

Вопрос

Есть ли в Python способ прослушивать нажатия клавиш, одновременно читая ввод по каналу?

Я обернул основную функцию в блок try, который исключает KeyboardInterrupt и печатает приятное маленькое прощальное сообщение вместо трассировки стека ошибок. Есть ли способ использовать это поведение с помощью другого ключа?

Я бы предпочел не использовать сложный (по сравнению с моим небольшим скриптом) модуль, такой как pygame или tkinter, и был бы вынужден использовать их основной цикл только для получения доступа к нажатиям клавиш. (также я не знаком с тем, как будет вести себя любой из них при получении входных данных по каналу)

1 Ответ

2 голосов
/ 01 ноября 2011

Самое простое решение - вообще не использовать трубу из хвоста. Придерживайтесь использования своего стандартного ввода для пользовательского ввода, и вместо этого напишите свой инструмент, чтобы он мог открывать и следовать за файлом, из которого вы хотите прочитать, без использования tail вообще. Хвост не очень сложный инструмент, если вы просто хотите переопределить эту часть.

В качестве альтернативы, вы можете создать именованный канал , который позволит вам подвести к нему хвост, и тогда ваша программа сможет читать его как файл и по-прежнему иметь доступ к своему собственному стандартному вводу.

Если ни один из этих вариантов не подходит, я думаю, что лучше всего выбрать отдельную библиотеку, которая напрямую опрашивает клавиатуру. Напомним, что в Pygame на самом деле нет «основного цикла», у него есть функция насоса событий, которую вы должны вызывать как можно чаще (в основном цикле), но если этого не произойдет, она не умрет. Он может буферизовать множество событий между насосами, и вы можете установить на него фильтры, чтобы отбрасывать все события, которые вам не нужны, и сохранять только те, которые вы делаете (нажатия клавиш). Основная проблема с pygame заключается в том, что для такого простого инструмента требуется довольно тяжелая библиотека, поэтому я понимаю, что вы не решаетесь пойти по этому пути.

О, и в качестве последнего варианта (на мой взгляд, наименее желательного) вы можете использовать механику прерываний клавиатуры для создания "Emacs-подобных" клавишных аккордов. Как, нажмите Ctrl-C, затем Ctrl- (что угодно). Ctrl-C вызывает KeyboardInterrupt, затем в обработчике вы читаете следующий символ из stdin и что-то делаете с этим. Как только вы закончите, вернитесь к своей петле. Но это безобразно и хакерски, и я даже не уверен, будет ли это работать надежно.

...