【问题标题】:Command raised an exception: AttributeError: 'Context' object has no attribute 'id' discord.py命令引发异常:AttributeError: 'Context' object has no attribute 'id' discord.py
【发布时间】:2021-08-14 23:23:23
【问题描述】:

我想用命令删除 JSON 文件中的公会 ID。

这是我的代码:

 @welcome.command(pass_context=True)
    @commands.has_permissions(administrator=True)
    async def reset(guild):
        with open('welcome.json', 'r') as f:
            welcome = json.load(f)
    
        welcome.pop(str(guild.id))
        with open('welcome.json', 'w',) as f:
            json.dump(welcomereset, f, indent=4)

这是错误消息:discord.ext.commands.errors.CommandInvokeError: 命令引发异常:AttributeError: 'Context' object has no attribute 'id'

我该如何解决这个问题?

【问题讨论】:

    标签: python discord.py


    【解决方案1】:
     @welcome.command() #pass_context is deprecated, every command will always get passes Context as first param.
     @commands.has_permissions(administrator=True)
     async def reset(ctx: commands.Context): #Just normal typehint for you to easily understand.
            with open('welcome.json', 'r') as f:
                welcome = json.load(f)
        
            welcome.pop(str(ctx.guild.id)) #ctx.guild -> discord.Guild and than .id for it's id. I would put an if statement to check if the command was even in a guild, so NoneType attribute error won't raise.
            with open('welcome.json', 'w',) as f:
                json.dump(welcomereset, f, indent=4)
    

    每个命令中的第一个参数是 ctx 或 context 代表 discord.ext.commands.Context 对象,如您所见,它没有 id。如果您试图获取调用命令的公会 ID,执行 ctx.guild 将返回 Optional[discord.Guild](如果命令是在私人频道中调用的)。如果它不是 None,你可以做 ctx.guild.id,这可能是你想要的。而且您不再需要 pass_context(用于传递 discord.ext.commands.Context btw)。这意味着现在,guild 是你的 Context 对象。

    【讨论】:

      【解决方案2】:

      每个命令中的第一个参数是ctxcontext 代表discord.ext.commands.Context 对象,如您所见,它没有id。如果您试图获取调用命令的公会 ID,则执行 ctx.guild 将返回 Optional[discord.Guild](如果在私人频道中调用了命令)。如果它不是 None,你可以做 ctx.guild.id,这可能是你想要的。而且您不再需要pass_context(用于传递discord.ext.commands.Context btw)

      【讨论】:

      • 这意味着现在,guild 是你的 Context 对象。
      【解决方案3】:

      由于您没有提到您的 discord.py 版本,我假设:

      - 1.0 之前的版本:

      你有pass_context=True,所以Context将作为函数的第一个参数传递。

      async def reset(guild): # The word 'guild' is actually a Context object
      

      名称guild 被定义为上下文,因此无论名称如何,它都遵循上下文的属性而不是公会。因此,您仍然可以使用 guild 并遵循 Context 的属性,但建议将 guild 编辑为 contextctx 以防止混淆。

      您也可以只做pass_context=False 并使guild 参数被用户接受为输入。

      - 1.0 以后的版本:

      从那时起pass_context参数就是removed,所以不管你是否使用这个,Context总是被传递。

      如上所述,您需要遵循 Context 的属性并使用适当的属性。在您的情况下,如果您需要访问调用该命令的公会的 id,您可以执行 ctx.guild.idctx 是指传递的 Context 对象)。

      async def reset(ctx):
          ...
          welcome.pop(str(ctx.guild.id))
          ...
      

      这会很好。

      P.S.:我不确定,但通过查看代码,我认为您在 .dump() 中传递了错误的参数 (welcomereset) 并希望传递 welcome。如果我错了,请忽略这个:P

      【讨论】:

      • 谢谢你,是的,你是对的,我也传递了错误的论点 xD
      猜你喜欢
      • 2021-07-17
      • 1970-01-01
      • 1970-01-01
      • 2022-08-15
      • 1970-01-01
      • 2019-05-28
      • 2022-12-03
      • 2022-12-01
      • 2023-01-02
      相关资源
      最近更新 更多