2013-09-15 2 views
0

В командной строке , я использую следующий код (от Andreas Renberg), чтобы задать пользователю вопрос «да/нет» (он просто использует стандарт input):Обработать escape-ключ как действие вместо символа на входе Python

# Taken from http://code.activestate.com/recipes/577058-query-yesno/ 
# with some personal modifications 
def yes_no(question, default=True): 
    valid = {"yes":True, "y":True, "ye":True, 
      "no":False, "n":False } 
    if default == None: 
     prompt = " [y/n] " 
    elif default == True: 
     prompt = " [Y/n] " 
    elif default == False: 
     prompt = " [y/N] " 
    else: 
     raise ValueError("invalid default answer: '%s'" % default) 

    while 1: 
     sys.stdout.write(question + prompt) 
     choice = input().lower() 
     if default is not None and choice == '': 
      return default 
     elif choice in valid.keys(): 
      return valid[choice] 
     else: 
      sys.stdout.write("Please respond with 'yes' or 'no' "\ 
          "(or 'y' or 'n').\n") 

Если пользователь yes (или эквивалент) функция возвращает True и no возвращает False. Если они просто нажимают Enter, то выбирается значение default.

Однако, если пользователь нажимает ESC на их клавиатуре, он получает рассматривается как символ. Есть ли способ заставить функцию возвращать False, если эта клавиша нажата? Несколько результатов, которые я нашел в моих собственных поисках, кажутся чрезмерно сложными или работают только с некоторыми операционными системами.

+1

'это расцениваться как character' - это не совсем верно, это зависит от того, лежащих в основе библиотеки используется. В моей системе (linux, которая использует readline, если доступна), нажатие 'Esc' на' input() 'promt ничего не делает. – mata

+0

Если вы находитесь на окнах, то может помочь модуль [msvcrt] (http://docs.python.org/2/library/msvcrt.html). –

+0

@AshwiniChaudhary Я в Ubuntu, и поскольку этот код предназначен для инструмента с открытым исходным кодом, код должен надежно работать на разных платформах. – IQAndreas

ответ

0

Если вы хотите поймать нажимную клавиатуру Esc, вам нужно реализовать что-то вроде getch, которое позволит вам получить по одному персонажу за раз.

Вот упрощенная реализация, которая работает.

if platform_is_windows: 
    from msvcrt import getch 

elif platform_is_posix: 
    import sys 
    import tty 
    import termios 

    def getch(): 
     fd = sys.stdin.fileno() 
     old_settings = termios.tcgetattr(fd) 
     try: 
      tty.setraw(sys.stdin.fileno()) 
      ch = sys.stdin.read(1) 
     finally: 
      termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) 
     return ch 

Тогда у вас есть только while цикл с getch, пока вы не получите Esc или Return.

Примечание: Я не указал способ определения платформы, так как существует несколько способов сделать это, и на этой теме есть много ответов на SO.

+0

Для окон есть 'Геч()' в стандартном модуле питона [MSVCRT] (http://docs.python.org/3/library/msvcrt.html). – TobiMarg

+0

@TobiMarg Спасибо за подсказку. Исправлена. Это действительно старый мир кода, и я понятия не имею, почему я использовал это вместо модуля msvcrt. –

+0

Это не сработает, потому что нажатие любого специального ключа, начинающегося с '\ x1b', запустит это ... –

Смежные вопросы