Windows Python 解释器在 Ctrl+C 时退出

Windows Python interpreter exits on Ctrl+C

对于我使用过的大多数 Python 解释器,Ctrl+C 将使解释器打印出“KeyboardInterrupt”并保持打开状态。但是,最近在新计算机上安装时,Ctrl+C 导致解释器退出,这是不可取的。

如果我在以下代码段的暂停期间按 Ctrl+C,解释器将保持打开状态。

import time

try:
    time.sleep(100)
except KeyboardInterrupt:
    pass

环境:Python 3.4.3 on Windows 10

当 Windows 8 及更高版本上 运行 时,shell 3.6 之前的 Python 版本的 Ctrl+C 处理被破坏。 inputraw_input 也被破坏了,你会得到 EOFError 而不是 KeyboardInterrupt。您可以通过安装和启用 win_unicode_console 或升级到 3.6

来解决此问题

问题是 Python 用于从控制台读取的旧代码取决于 ReadFile 在读取被 Ctrl+ 中断时将最后一个错误设置为 ERROR_OPERATION_ABORTED (995) C。在 Windows 8 中,Microsoft 完全重写了客户端进程与控制台的通信方式。在这种情况下,他们这样做违反了 ReadFile 行为的记录合同。如果没有错误,Python 认为中止的读取是对 0 字节的成功读取。通常这表示文件结束 (EOF),因此 REPL 会简单地退出,就像用户键入 Ctrl+Z、Enter 一样。

ReadFile 是从任何文件句柄的一般读取。还有一个专门的 ReadConsole 函数。这个仍然可以正常运行,这就是 win_unicode_console 和 3.6+ 没有这个问题的原因。他们调用 ReadConsoleW 来解决在控制台中使用全系列 Unicode 的单独问题,而这恰好也解决了 Ctrl+C 问题。


仅供参考,您在屏幕上看到的 ^C 不是由控制台 (conhost.exe) 或 Python 写入的。它实际上是由 cmd.exe shell 设置的 CTRL_BREAK_EVENT 处理程序打印的。如果您使用 PowerShell 运行 Python,您应该看不到使用 Ctrl+Break 打印的内容。