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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:46:13