防止 Python 在 ctrl-D 上退出

防止 Python 在 ctrl-D 上退出

我发现以下情况经常发生在我身上:

  1. 我在交互式终端会话中使用 Python
  2. 我不小心输入了一些括号不匹配的内容
  3. Python 给我一个...提示,希望我输入另一行代码
  4. 为了回到 Python 命令提示符,我本能地输入ctrl-D(传输结束字符)
  5. Python 进程没有返回到>>>提示符,而是立即退出,丢失了我交互会话中的所有数据

我希望这种情况不再发生。因此我的问题是:

  • 有没有办法可以防止ctrl-D按下 时 Python 退出?

  • 这可能只是一厢情愿,但是有什么方法可以让ctrl-D我回到我一直期望的 Python 提示符?

我在 Mac 上使用 MacPorts 安装的 Python 3.6,但我想这是一个与平台无关的问题。我相信此安装使用 Gnu Readline 库进行用户交互,以防万一。

答案1

在使用“cooked”模式的基本程序中,例如catCtrl+D在tty层上挂接为结束语字符 - 它不会直接发送给进程,而是生成“EOF”条件,导致进程突然从其调用中收到 0 字节结果read(stdin)。(进程可以只记录该条件并继续。)

理论上,由于 Python 使用 Readline,因此它不受此影响;它以“cbreak”模式使用终端,并让 Readline 处理所有特殊字符,包括 Ctrl+D。(也就是说,按下该键只会从 read 返回“\x04”,然后由 Readline 绑定在内部处理。)

然而,Readline 会自动绑定它在 tty 层上看到的已绑定的控制字符,并且没有选项可以从 Python 内部控制它。(尽管它有一个 ~/.inputrc 选项,但它似乎在 Python 中被忽略了。)

有没有办法可以防止按下 ctrl-D 时 Python 退出?;

因此似乎没有办法阻止 Python 的 readline 将 Ctrl+D 处理为 EOF除非tty 层有结束语绑定到其他内容(但并非完全解除绑定)。您唯一的选择是在 tty 层临时将 EOF 字符重新定义为除 Ctrl+D 之外的其他内容(使用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 和大多数 shell 一样,接受 SIGINT 来执行此操作。

相关内容