Я считаю, что со мной часто случается следующее:

  1. Я использую Python в сеансе интерактивного терминала
  2. Я случайно что-то набираю с несбалансированными скобками
  3. Python дает мне ... Подскажите, ожидая меня , чтобы ввести еще одну строку кода
  4. В попытке вернуться в командную строку Python я инстинктивно ctrl-D (символ конца передачи)
  5. Вместо того, чтобы вернуться к приглашению >>> , процесс Python немедленно завершается, теряя все данные из моего интерактивного сеанса.

Я бы хотел, чтобы этого больше не было. Поэтому мои вопросы:

  • Есть ли способ предотвратить выход Python при нажатии ctrl-D ?;

  • Это может быть бесполезным, но могу ли я заставить ctrl-D вернуть меня к приглашению Python, как я и ожидал?

Я использую Python 3.6, установленный с MacPorts на Mac, но я думаю, что это довольно независимый от платформы вопрос. Я полагаю, что эта установка использует библиотеку Gnu Readline для взаимодействия с пользователем в случае необходимости.

1 ответ1

0

В базовых программах, в которых используется режим «cooked», таких как cat , Ctrl+D подключается к tty-слою как символ eof - он не отправляется непосредственно процессу, но генерирует условие «EOF», вызывая внезапный процесс получить 0-байтовый результат от его вызова read(stdin) . (Процесс может просто записать условие и продолжить.)

Теоретически, поскольку Python использует Readline, это не затрагивается; он использует терминал в режиме 'cbreak' и позволяет Readline выполнять обработку всех специальных символов, включая Ctrl+D. (Таким образом, нажатие клавиши просто вернет «\x04» из чтения, которое затем обрабатывается внутренне привязками Readline.)

Однако Readline автоматически связывает те же управляющие символы, которые он видит уже привязанными к слою tty, и не имеет возможности управлять этим изнутри Python. (Хотя он имеет опцию ~/.inputrc, в Python он игнорируется.)

Есть ли способ предотвратить выход Python при нажатии Ctrl-D?;

Таким образом, кажется , что нет никакого способа , чтобы остановить Readline Python от обработки Ctrl+D , как EOF , если терминал слой не ВФ связан с чем - то другим (но не полностью несвязанным). Единственный вариант - временно переопределить символ EOF, чтобы он был чем-то иным, чем Ctrl+D на слое tty (используя stty eof), и переопределить его до правильного значения при выходе.

Попробуйте добавить это в свой файл $ PYTHONSTARTUP:

if True:
    import atexit, os
    os.system("stty eof ^X")
    atexit.register(lambda: os.system("stty eof ^D"))

(Обратите внимание, что полностью неопределенный eof здесь не будет работать - если Readline найдет ноль, он примет Ctrl+D по умолчанию.)

Независимо от вышесказанного, если я введу несоответствующие скобки, как правильно выйти из приглашения ... и вернуться к >>> без запуска введенного мной кода?

Нажмите Ctrl+C. Python принимает SIGINT для этого, как и большинство оболочек.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .