You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python按键记录器调用write函数写入文件出现乱码问题求助

问题根因
  • 遍历逻辑错误:你向keys列表中存入的是(按键对象, 时间戳)组成的二元组,但后续循环写入时直接把整个元组转为字符串,而非取出元组内的按键对象处理,引入了大量非预期结构字符。
  • 文件编码未显式指定:Python的open()函数在Windows系统下默认使用GBK/CP936编码写入文件,而代码生成的字符串为Unicode编码,编码映射不匹配直接导致写入乱码,控制台打印正常是因为控制台默认适配了Python的Unicode输出规则。
修复方案
  1. 循环时取出元组内的第一个元素作为按键处理对象
  2. 调用open()时增加encoding='utf-8'参数,强制使用UTF-8编码写入,适配全字符集
  3. 优化按键转字符串逻辑,区分普通可打印字符和特殊功能键,过滤多余格式字符

修正后可正常运行的代码如下:

from timeit import default_timer as timer
from pynput.keyboard import Key, Listener

keys = []

def key_press(key):
    global keys
    start = timer()
    if key == Key.esc:
        return False

    keys.append((key, start))

    if key == Key.enter:
        # 显式指定utf-8编码写入
        with open("log-5.txt", "w", encoding="utf-8") as f:
            for key_item, ts in keys:
                # 区分普通字符和特殊按键处理
                if hasattr(key_item, 'char') and key_item.char is not None:
                    k = key_item.char
                else:
                    k = f"[{key_item.name}]"
                # 如需同时记录时间戳可以改成 f.write(f"{k} {ts}\n")
                print(k)
                f.write(k + "\n")
        keys = []


with Listener(on_press=key_press) as listener:
    listener.join()
补充说明

如果需要保留时间戳记录,不要直接对元组执行str()转换,单独格式化时间戳后拼接内容再写入即可,避免引入多余结构字符。

内容的提问来源于stack exchange,提问作者thome.steve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 17:15:04