为何我的bool变量is_on无法在True和False间正常切换?
问题修复方案
你的代码存在几个关键问题,导致热键只能切换一次状态:
- 变量作用域问题:
on_off函数里的is_on是局部变量,修改它根本不会改变全局的is_on值,所以第二次按热键时,全局状态还是False,等于白切换。 - 线程实现错误:
loop是普通函数,不能直接调用.start();就算能调用,你传进去的is_on是布尔值(不可变类型),线程里拿到的是副本,后续全局状态变化了,线程里的判断也不会更新。 - 热键绑定逻辑混乱:原代码里
lambda: on_off(is_on).start()完全不成立,因为on_off没有返回线程对象,这么写会直接报错。
下面是修正后的代码:
import time import threading from pynput import keyboard is_on = False print_thread = None # 保存打印线程的引用,防止重复创建 def for_canonical(input_func): return lambda key: input_func(listener.canonical(key)) def toggle_state(): global is_on, print_thread is_on = not is_on if is_on: # 启动后台打印线程,daemon=True让线程随主线程退出 print_thread = threading.Thread(target=loop, daemon=True) print_thread.start() def loop(): # 直接读取全局的is_on,每次循环都检查最新状态 while is_on: print("some text") time.sleep(1) print("some text") time.sleep(1) print("some text") time.sleep(1) print("some text") time.sleep(1) # 绑定热键到状态切换函数 hotkey = keyboard.HotKey(keyboard.HotKey.parse("<alt>+n"), toggle_state) listener = keyboard.Listener( on_press=for_canonical(hotkey.press), on_release=for_canonical(hotkey.release) ) listener.start() # 让主线程保持运行,否则程序会直接退出 listener.join()
关键修改点
- 用
global关键字在toggle_state里声明要修改的全局变量,确保状态切换能同步到全局。 - 改用
threading.Thread创建打印线程,设置daemon=True避免程序退出后线程还在跑。 loop函数直接检查全局的is_on,这样状态切换后,下一次循环就会停止。- 简化热键绑定逻辑,直接指向
toggle_state函数,去掉多余的嵌套。
内容的提问来源于stack exchange,提问作者user22574473
相关产品推荐
相关产品推荐

