如何在Python中检测ESCape keypress?

Ala*_*eid 8 python windows escaping keypress

我正在命令窗口(Windows 7,Python 3.1)中运行一个进程,我希望用户通过按ESCape键来中止该进程.但是,按下ESCape键似乎没有做任何事情:-(,循环永远不会中断.我也尝试从我的IDE(Wing)中运行脚本,但同样,循环不能被中断.

以下是我的概念验证测试的精简版...

import msvcrt
import time

aborted = False

for time_remaining in range(10,0,-1):
    # First of all, check if ESCape was pressed
    if msvcrt.kbhit() and msvcrt.getch()==chr(27):
        aborted = True
        break

    print(str(time_remaining))       # so I can see loop is working
    time.sleep(1)                    # delay for 1 second
#endfor timing loop

if aborted:
    print("Program was aborted")
else:
    print("Program was not aborted")

time.sleep(5)  # to see result in command window before it disappears!
Run Code Online (Sandbox Code Playgroud)

如果有人能告诉我哪里出错了,我将非常感激.

Ade*_*mro 6

Python 3字符串是unicode,因此必须编码为字节以进行比较.试试这个测试:

if msvcrt.kbhit() and msvcrt.getch() == chr(27).encode():
    aborted = True
    break
Run Code Online (Sandbox Code Playgroud)

或者这个测试:

if msvcrt.kbhit() and msvcrt.getch().decode() == chr(27):
    aborted = True
    break
Run Code Online (Sandbox Code Playgroud)

或者这个测试:

if msvcrt.kbhit() and ord(msvcrt.getch()) == 27:
    aborted = True
    break
Run Code Online (Sandbox Code Playgroud)


Wan*_*wei 5

你真的应该减少更多,就像下面这个:

>>> import msvcrt
>>> ch = msvcrt.getch()
# Press esc
>>> ch
b'\x1b'
>>> chr(27)
'\x1b'
>>> ch == chr(27)
False
Run Code Online (Sandbox Code Playgroud)

所以这里是问题:msvcrt.getch()返回byteschr(27)返回string。在 Python 3 中,它们是两种不同的类型,因此 " ==" 部分永远不会起作用,并且if语句将始终被评估为False.

解决方案对您来说应该是显而易见的。

更多关于字符串与字节的信息,来自 Dive into Python 3 一书。

交互式控制台对于调试非常有用,请尝试使用更多:)


Joh*_*hin 5

你不需要编码,解码,chr,ord,....

if msvcrt.kbhit() and msvcrt.getch() == b'\x1b':
Run Code Online (Sandbox Code Playgroud)

或者如果你想在代码中看到"27":

if msvcrt.kbhit() and msvcrt.getch()[0] == 27:
Run Code Online (Sandbox Code Playgroud)


ana*_*nik 5

Python 2/3 兼容代码:

import time, sys

ESC = '\x1b'
PY3K = sys.version_info >= (3,)
if PY3K:
    from msvcrt import kbhit, getwch as _getch
else:
    from msvcrt import kbhit, getch as _getch
while not kbhit() or _getch() != ESC:
    print(time.asctime())
    time.sleep(1)
Run Code Online (Sandbox Code Playgroud)

代码部分取自pager包含更多内容的模块。