Предотвращение выхода Python на Ctrl-D

586
Nathaniel

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

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

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

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

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

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

0

1 ответ на вопрос

0
grawity

В базовых программах, которые используют режим «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 для этого, как и большинство оболочек.