discord.py开发日志存储命令报错TypeError: unhashable type: 'list'如何解决
报错根因与解决方案
你遇到的TypeError: unhashable type: 'list'报错是代码写错了字典访问键直接导致的:
你编写的logCount = logsJson[messages][-1]["count"] + 1中,把存储频道消息的列表变量messages当成了字典logsJson的访问键,而列表是不可哈希类型,不能作为字典的键使用,因此抛出对应报错。你实际要访问的是日志列表logsJson["messageLogs"],修正该行代码为以下内容即可解决当前报错:
# 兼容首次写入日志时messageLogs为空的边界情况 logCount = logsJson["messageLogs"][-1]["count"] + 1 if logsJson.get("messageLogs", []) else 1
其他已知问题与修复方案
你的代码还存在多处逻辑错误、类型错误,运行时会触发后续报错,统一修复方案如下:
- 不可序列化对象写入JSON报错
你直接将ctx.author(Discord用户对象)、msg.created_at(datetime时间对象)、msg.attachments(附件对象列表)存入字典,这些类型都无法被JSON直接序列化,需要提前转成基础类型:- 用户对象转字符串/用户ID:
str(ctx.author)、ctx.author.id - 时间对象转时间字符串:
msg.created_at.strftime("%Y-%m-%d %H:%M:%S") - 附件列表提取URL存储:
[att.url for att in msg.attachments]
- 用户对象转字符串/用户ID:
- 逻辑中断错误
遍历消息时遇到Bot发送的消息你直接用了return终止整个函数,会导致已打开的文件没有关闭、日志写入中断,将return改为continue跳过Bot消息即可。 - 文件路径转义错误
路径中的反斜杠\是Python字符串的转义字符,会导致路径识别异常,建议用os.path.join拼接路径,或者改为正斜杠/。 - 文件写入格式错误
用r+模式打开文件直接执行json.dump会在原有内容后追加写入,导致JSON格式损坏,读取完原有内容后需要先将文件指针移到开头,写入后截断多余内容:logsFile.seek(0) json.dump(logsJson, logsFile, indent=2, ensure_ascii=False) logsFile.truncate() - 异步方法未加
await
删除消息的方法logMsg.delete()是异步方法,必须加await才会正常执行,修正为await logMsg.delete()。 - 日志索引匹配错误
你用logCount作为logsJson["messageLogs"]的下标访问,容易出现计数与索引不匹配的问题,新添加的日志条目直接用-1取列表最后一项即可:logsJson["messageLogs"][-1]["msgs"].append(newMessage)
修正后核心代码示例
# 加载已有日志文件 import os log_path = os.path.join(currentDirectory, "Saved", "logs.json") with open(log_path, "r", encoding="utf-8") as f: logsJson = json.load(f) # 创建新日志条目 logCount = logsJson["messageLogs"][-1]["count"] + 1 if logsJson.get("messageLogs", []) else 1 newLog = { "name": logName, "creator": str(ctx.author), "creator_id": ctx.author.id, "msgs": [], "count": logCount } logsJson["messageLogs"].append(newLog) # 记录消息 for msg in messages: msgAuthor = msg.author if msgAuthor.bot: continue msgContent = msg.content msgAttachments = [att.url for att in msg.attachments] msgCreated = msg.created_at.strftime("%Y-%m-%d %H:%M:%S") msgWrite = f'\n{msgAuthor} [{msgCreated}]\n{msgContent}' newMessage = { "id": msg.id, "authorname": str(msgAuthor), "authorid": msgAuthor.id, "content": msgWrite, "published": msgCreated, "attachments": msgAttachments } logsJson["messageLogs"][-1]["msgs"].append(newMessage) # 写入更新后的日志 with open(log_path, "w", encoding="utf-8") as f: json.dump(logsJson, f, indent=2, ensure_ascii=False) # 命令执行结束 await logMsg.delete() desc = f'**Finished Logging**' endEmbed = discord.Embed(title = f'**Log**', description = desc, colour = discord.Color.from_rgb(36, 227, 170)) await ctx.send(embed = endEmbed)
内容的提问来源于stack exchange,提问作者Anonyo Noor
相关产品推荐
相关产品推荐

