discord.py JSON报告系统Member对象JSON序列化错误求助
Discord.py报告/建议系统JSON序列化问题解决
问题场景
基于discord.py开发报告/建议提交系统,使用JSON文件作为临时存储,计划保存提交用户信息、内容类型(报告/建议)及具体内容,但运行时触发TypeError,提示Member对象无法被JSON序列化。
原实现代码
class my_modal(ui.Modal, title="Report or Suggest"): answer = ui.TextInput(label="Is this a report or a suggestion?", style=discord.TextStyle.short, required=True, placeholder="Report/Suggestion") answer2 = ui.TextInput(label="What is your report/suggestion?", style=discord.TextStyle.long, required=True, placeholder="Your Text Here") async def on_submit(self, interaction: discord.Interaction): with open("reports.json", "r") as f: data = json.load(f) if self.answer.value.lower() == "report" or self.answer.value.lower() == "suggestion": await interaction.response.send_message("Successfully submitted your report/suggestion.", ephemeral=True) print(f"{interaction.user} sent a {self.answer}: {self.answer2}") data["name"] = interaction.user data["choice"] = self.answer.value.lower() data["message"] = self.answer2.value.lower() with open("reports.json", "w") as f: json.dump(data, f) else: await interaction.response.send_message("You either didn't put a valid input in your first choice or didn't type it properly. Make sure you typed it properly and try again.", ephemeral=True) return @client.tree.command() @commands.guild_only() async def report(interaction: discord.Interaction): await interaction.response.send_modal(my_modal())
报错信息
Traceback (most recent call last): File "/home/container/.local/lib/python3.9/site-packages/discord/ui/modal.py", line 186, in _scheduled_task await self.on_submit(interaction) File "/home/container/main.py", line 311, in on_submit json.dump(data, f) File "/usr/local/lib/python3.9/json/__init__.py", line 179, in dump for chunk in iterable: File "/usr/local/lib/python3.9/json/encoder.py", line 431, in _iterencode yield from _iterencode_dict(o, _current_indent_level) File "/usr/local/lib/python3.9/json/encoder.py", line 405, in _iterencode_dict yield from chunks File "/usr/local/lib/python3.9/json/encoder.py", line 438, in _iterencode o = _default(o) File "/usr/local/lib/python3.9/json/encoder.py", line 179, in default raise TypeError(f'Object of type {o.__class__.__name__} ' TypeError: Object of type Member is not JSON serializable
问题原因
JSON只能序列化Python内置的基本数据类型(字符串、数字、列表、字典等),而interaction.user是discord.py提供的Member类实例,属于自定义对象,无法直接被JSON序列化。此外原代码每次提交会覆盖JSON中的现有数据,无法保存多条记录。
解决方法
1. 存储可序列化的用户信息
不要直接存储Member对象,改为存储用户的唯一标识和可读信息:
- 用户ID:转成字符串存储(避免JSON处理大数字时的精度丢失)
- 用户名:转成字符串存储(格式如
用户名#标签)
2. 优化数据存储结构
将JSON结构改为列表形式存储多条提交记录,避免覆盖旧数据。
修改后的核心代码
async def on_submit(self, interaction: discord.Interaction): # 处理JSON文件不存在的情况,初始化空结构 try: with open("reports.json", "r", encoding="utf-8") as f: data = json.load(f) except FileNotFoundError: data = {"submissions": []} input_type = self.answer.value.lower() if input_type in ["report", "suggestion"]: await interaction.response.send_message("已成功提交你的报告/建议。", ephemeral=True) print(f"{interaction.user} 提交了一个{input_type}:{self.answer2.value}") # 构造可序列化的提交数据 new_submission = { "user_id": str(interaction.user.id), "username": str(interaction.user), "type": input_type, "content": self.answer2.value } # 添加到提交列表 data["submissions"].append(new_submission) # 写入JSON文件,添加indent让格式更清晰 with open("reports.json", "w", encoding="utf-8") as f: json.dump(data, f, indent=2, ensure_ascii=False) else: await interaction.response.send_message("请输入有效的类型:Report或Suggestion,检查拼写后重试。", ephemeral=True) return
额外说明
- 若后续需要通过用户ID获取用户对象,可以使用
await interaction.guild.fetch_user(user_id)方法 - 添加
encoding="utf-8"和ensure_ascii=False可以支持中文等非ASCII字符的存储和读取
内容的提问来源于stack exchange,提问作者TheRealKurumi
相关产品推荐
相关产品推荐

