【问题标题】:On reaction change variable from another async function来自另一个异步函数的反应更改变量
【发布时间】:2021-09-04 17:52:15
【问题描述】:

我正在开发一个用于创建投票的不和谐机器人,我的代码在这里:

@bot.command(name="newpoll")
async def new_poll(ctx, question, *options):
    if len(options) > 12:
        await ctx.send("You can have a maximum of 12 choices in your poll")

    else:
        embed = discord.Embed(title = "Poll",
                              description = question,
                              colour = discord.Colour.red())

        fields = [("Options", "\n".join([f"{emotes[idx]} {option}" for idx, option in enumerate(options)]), False),
                  ("Instructions", "Please react in order to vote!", False)]

        for name, value, inline in fields:
            embed.add_field(name = name, value = value, inline = inline)

        embed = embed.add_field(name = "Total votes", value = 0, inline = False)
        message = await ctx.send(embed = embed)

        for emoji in emotes[:len(options)]:
            await message.add_reaction(emoji)

        message_win = await bot.get_channel(message.channel.id).fetch_message(message.id)
        total_votes = sum(reaction.count for reaction in message_win.reactions) - len(options)

        tv_embed = embed.set_field_at(2, name = "Total votes", value = total_votes, inline = False)
        await message.edit(embed = tv_embed)


总投票数存储在total_votes 变量中,我计划通过编辑嵌入消息(如最后两行)来显示该变量。我希望在发生反应时发生这种情况。关于这一点,我尝试使用类似于以下的代码访问tv_embed

@bot.event
async def on_reaction_add(reaction, user):
    print("planning to ember.set_field_at(...) here")
    from_new_poll = await new_poll.tv_embed
    from_new_polll = await new_poll.message
    await from_new_polll.edit(embed = from_new_poll)

但我得到类似这样的错误:

planning to ember.set_field_at(...) here
Ignoring exception in on_reaction_add
Traceback (most recent call last):
  File "/home/vale/.virtualenvs/discord_env/lib/python3.9/site-packages/discord/client.py", line 343, in _run_event
    await coro(*args, **kwargs)
  File "/home/vale/Documents/arcane/e_project-kindling/Discord-Bot/main.py", line 108, in on_reaction_add
    from_new_poll = await new_poll.tv_embed
AttributeError: 'Command' object has no attribute 'tv_embed'

谁能解释一下这里发生了什么,提前谢谢!

【问题讨论】:

    标签: python discord.py python-asyncio


    【解决方案1】:

    一个简单的方法可以是使用字典或其他数据结构,可以从任何地方访问,例如:

    # after your bot instantiation (or at __init__)
    bot = commands.Bot(...)
    bot.polls = {}
    
    # In same file commands:
    @bot.command()
    async def test(ctx):
      print(bot.polls)
    
    #In cogs:
    self.bot.polls
    ctx.bot.polls
    

    现在在您的投票命令中

    msg = await ctx.send(...)
    author_polls = bot.polls.setdefault(author, [])
    author_polls.append(msg)
    

    最后,在您的事件处理程序中

    msg = reaction.message
    polls = bot.polls.get(msg.author)
    if polls and msg in polls:
      ... # we know this reaction happened in a message that has a poll
    

    在这个例子中,我只是存储了原始消息,但你可以在那里存储你需要的任何东西。

    请考虑这是不安全的,因为重新启动会清除数据并破坏它。您应该使用数据库并存储您想要的任何 ID。您可以在启动时加载它并构建字典,然后在每次新的轮询时更新它。

    【讨论】:

      【解决方案2】:

      您无法访问在另一个函数中定义的变量,它们仅在该函数的内部可见,因此在其他任何地方都不可见。 new_poll.tv_embed 本质上与any_command.tv_embed 相同,因为tv_embed 变量对外界不可见。如果您不知道这一点,我建议您稍微了解一下scopes

      如果您想访问它,您必须将其存储在函数之外的某个位置(例如,作为变量在您的 Cog 中或在您的 .py 文件中的其他位置)。

      我必须指出,如果您尝试做这样的事情,则会出现更大的问题,并且您的代码的整体设计刚刚结束。这几乎是从不的方式。在您的情况下,您可以从 reaction 参数访问原始嵌入并立即对其进行编辑,而无需将其存储在任何地方。

      @bot.event
      async def on_reaction_add(reaction, user):
          # "reaction" has a "message" field that contains a reference to the message that the reaction was placed on
          message = reaction.message
          # A "Message" has a list of all embeds attached to this message, in your case I assume there's only one
          tv_embed = message.embeds[0]
      

      请注意,对于没有任何embeds 的消息,上面的 ^ 会崩溃,它只是作为示例来给你一个想法,而不是一个成熟的解决方案。你需要一些if-statements 来检查你是否应该编辑这个嵌入,所以检查是否有 is 一个嵌入开始。不过,这应该足以让您继续前进,而这些支票由您来写。

      有关详细信息,请参阅on_reaction_adddiscord.Reactiondiscord.Message 的 API 文档。

      【讨论】:

      • 非常感谢,先生,您的详细回答,按照您的建议查看了scopescog,现在看来最好学习和使用cog 而不是我原来的接近。
      • 如果这解决了您的问题,请记住接受答案。
      猜你喜欢
      • 1970-01-01
      • 2019-06-27
      • 1970-01-01
      • 1970-01-01
      • 2022-11-14
      • 1970-01-01
      • 2020-05-25
      • 2021-11-26
      • 2017-01-24
      相关资源
      最近更新 更多