You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python使用keyboard包时无法正常退出脚本的问题

Python使用keyboard包时无法正常退出脚本的问题

嘿,我来帮你捋捋这个问题~先看看你的代码:

import keyboard

def onEsc(e):
    if e.event_type == keyboard.KEY_DOWN and e.name == 'esc':
        print("Goodbye")
        exit(1)

keyboard.on_press_key('esc', onEsc)

while True:
    None

问题原因

其实核心问题出在线程模型上:keyboard库的回调函数是在独立的后台线程里执行的,而exit()或者sys.exit()只能终止当前线程(也就是这个回调所在的子线程),但你的主线程还卡在那个while True的死循环里,所以整个脚本根本不会退出。至于第二次按Esc没反应,是因为第一次触发时子线程已经被exit()终止了,自然不会再执行回调逻辑。

解决方案

给你几个实用的解决办法,按推荐程度排序:

1. 用全局变量控制主线程循环(最稳妥)

通过一个全局标记来让主线程的循环正常结束,这样脚本就能优雅退出:

import keyboard
import time

running = True

def onEsc(e):
    global running
    if e.event_type == keyboard.KEY_DOWN and e.name == 'esc':
        print("Goodbye")
        running = False

keyboard.on_press_key('esc', onEsc)

while running:
    time.sleep(0.1)  # 加个sleep避免空循环占用过多CPU

2. 用keyboard.wait()替代手动死循环

keyboard库本身提供了阻塞主线程的方法,不用自己写while True

import keyboard

def onEsc(e):
    if e.event_type == keyboard.KEY_DOWN and e.name == 'esc':
        print("Goodbye")
        keyboard.unhook_all()  # 先解绑所有钩子,避免后续触发

keyboard.on_press_key('esc', onEsc)
keyboard.wait()  # 这个方法会自动阻塞主线程,直到钩子触发或进程中断

3. 强制终止整个进程(不推荐,仅应急用)

如果实在需要快速终止,可以用os._exit()直接干掉整个进程,不过这种方式不会执行任何清理操作,比如关闭文件、释放资源等:

import keyboard
import os

def onEsc(e):
    if e.event_type == keyboard.KEY_DOWN and e.name == 'esc':
        print("Goodbye")
        os._exit(1)  # 直接终止所有线程,整个脚本立刻结束

keyboard.on_press_key('esc', onEsc)

while True:
    None

备注:内容来源于stack exchange,提问作者sadcat_1

火山引擎 最新活动