【发布时间】:2021-03-15 17:22:14
【问题描述】:
我试图在我的 discord 机器人中实现的是一个系统,该系统会在同一用户调用另一个命令时立即停止正在运行的命令协程,以尝试为每个用户保持唯一的活动会话。
所以本质上我需要能够访问那个协程对象并从另一个协程中停止它。
到目前为止,我所尝试的方法在我看来是合乎逻辑的,但我确信对于 discord API 如何处理协程存在一些误解。这是一个基本示例:
active_sessions = {}
@bot.command()
async def first_command(ctx):
# Saving the coroutine in the dictionary with the user ID as key:
active_sessions[ctx.author.id] = ctx.command.callback
# do stuff
@bot.command()
async def second_command(ctx):
# Accessing the coroutine object and trying to stop it.
try:
coro = active_sessions[ctx.author.id]
coro.close()
except KeyError:
pass
抛出一个AttributeError 声明函数对象没有关闭属性。
但是,根据 discord.py 文档,command.callback 指的是应该具有 close 方法的协程对象。还尝试了coro.cancel(),结果相同。
我在这里在概念上做错了,但我不确定到底是什么,而且我不知道如何正确实施我的想法,所以非常感谢任何帮助。
编辑
所以,由于我的目标可能还不清楚,这就是我想要完成的目标。
我正在制作一个类似于游戏的不和谐机器人。用户可以运行多个命令,其中许多命令会等待一定的时间以等待命令作者的反应或消息。
但是这个用户可能在没有“完成”第一个命令的情况下运行另一个命令,如果他们回到第一个命令,他们的反应仍然会被接受。
我试图避免这种行为,并让用户专注于“单一会话”;无论他们运行什么命令,前一个命令的执行都需要自动停止。
因此,由于对协程的错误误解,我是如何实现这一点的,即拥有一个字典,将每个用户与您当前正在运行的命令的循环相关联。如果另一个循环开始时另一个循环仍在运行,则“旧循环”将停止,字典中的相应条目将使用新循环更新:
active_sessions = {}
@bot.command()
async def first_command(ctx):
# In this first command I want to assign the current loop to a variable and
# add it to the active_sessions dictionary along with the ID of the command author.
# Then there's a loop that waits for user's reaction.
# Ignore the details such as the check function.
while True:
try:
reaction, user = await bot.wait_for("reaction_add",timeout=60,check=check)
# some if conditions here make the bot behave differently according
# to the specific reaction added
except asyncio.TimeoutError:
return
@bot.command()
async def second_command(ctx):
# As soon as this second command is invoked, I need to access the 'loop object'
# previously stored in the dictionary (if any) and stop it from here.
【问题讨论】:
-
您到底想达到什么目的。
coro.cancel?ctx.command.callback返回的是协程,不是可以取消的运行循环 -
感谢您的评论。是的,我确定我指的是错误的对象。如果可能的话,我如何管理来自另一个循环的特定循环?
-
确实如此。但是你应该说清楚,你想要阻止或控制什么?你现在的方法肯定行不通。更深入地了解您正在尝试做的事情将有助于轻松获得答案。
-
编辑了更多信息。
标签: python discord discord.py coroutine