Python 如何在内部诅咒时启动键盘中断

Python 如何在内部诅咒时启动键盘中断,python,python-2.7,curses,pdcurses,Python,Python 2.7,Curses,Pdcurses,使用Windows()上的curses模块,我试图在KeyboardInterrupt异常上中断,但当我按下ctrl+c时,它不会出现 一些经过提炼的代码: from curses import wrapper items = ['a', 'very', 'long', 'list', 'of', 'strings'] def main(screen): for item in items: screen.addstr(0, 0, item) scree

使用Windows()上的
curses
模块,我试图在
KeyboardInterrupt
异常上中断,但当我按下ctrl+c时,它不会出现

一些经过提炼的代码:

from curses import wrapper
items = ['a', 'very', 'long', 'list', 'of', 'strings']

def main(screen):
    for item in items:
        screen.addstr(0, 0, item)
        screen.getch()
        screen.refresh()

wrapper(main)
items
列表很长,现在我不能中途停止执行。我必须反复按键直到结束。天哪,我决不会在一个
中尝试这一点,而真正的:


当我按ctrl+c时,不会引发异常。它确实作为
3
传递到我的
getch()。当
getch
接收到
3
时,SOP是否手动启动,或者是否有更合适的方法避免吞咽
键盘中断

默认情况下
诅咒
使用模式,从文档中关闭中断/退出/暂停等

在原始模式下,正常线路缓冲和中断处理,退出, 暂停,并关闭流量控制键;人物是 一个接一个地呈现给curses输入函数

从C的诅咒中:

这两个函数(
raw
cbreak
)之间的区别在于 控制字符的方式,如挂起(CTRL-Z)、中断和退出 (CTRL-C)传递给程序
raw()模式下
字符直接传递给程序,而不生成
信号。

由于python在发送
SIGINT
时会引发
KeyboardInterrupt
,因此预计不会引发该事件。您看到的
3
确实表示中断

由于这是由C库处理的,因此无法避免这种异常的“吞咽”。但是,您可以为
getch
使用一个简单的包装器,该包装器在返回
3
时进行检查,并相应地引发错误。

使用UGETCHAR(在下面实现)而不是
getch

def UGETCHAR_(scr):
    import curses
    h = scr.getch()
    if h == 3:
        raise KeyboardInterrupt
    if h == 26:
        raise EOFError
    return h
让我解释一下

因此,当调用该函数时,它首先导入
诅咒
[
导入诅咒
]

接下来,它运行您正在使用的getch(),并将结果放入名为
h
的变量中。[
h=scr.getch()
]

然后,如果
h
为3(
^C
)[
如果h==3:
],它将引发键盘中断[
raisekeyboardinterrupt
],如果
h
为26(
^Z
)[
如果h==26:
],它将引发EOFError[
键盘中断[/code>]


最后,它返回
h
[
returnh
]的值。

这个问题很久以前就被问过了,但我遇到了完全相同的问题。我想要一个使用诅咒的Python程序在Windows和Linux上运行。键盘中断在Linux上的工作方式与预期完全相同,但在Windows上则不然。我尝试了所有的curses设置函数,但始终无法使用Ctrl+C来打断执行

下面的代码似乎可以工作,但并不理想。到目前为止,我还没有找到更好的方法。Windows上这种方法的问题在于它不会中断。在检查输入之前,代码将在当前循环迭代中执行任何工作。(它在Linux上仍然可以完美地工作。)

Linux上的输出:

Main starting.  Ctrl+C to exit.
Do work in loop. i=4

Ctrl+C detected, Program Stopping
Program cleanup
Windows上的输出:

Main starting.  Ctrl+C to exit.
Do work in loop. i=6
getch() got Ctrl+C
Ctrl+C detected, Program Stopping
Program cleanup

非常感谢。这是有道理的。在阅读文档时,我似乎需要将
curses.noqiflush()
curses.noraw()
、或
curses.cbreak()
组合在一起,但这些都不能改变行为。我想我将只包装我的
getch
以检查
3
或ctrl+z的
26
PDCurses模拟基于Unix的诅咒行为,但是对于像这样的低级东西,它永远不会完全匹配。在Unix上,终端总是处于原始模式(how-to是误导性的),而curses模拟其他模式。OP询问的是Windows,而不是Linux(期望差异)。这种比较似乎与进行跨平台开发的读者完全相关。
Main starting.  Ctrl+C to exit.
Do work in loop. i=6
getch() got Ctrl+C
Ctrl+C detected, Program Stopping
Program cleanup