需要多个 wait_for_messages discord.py

2022-01-15 00:00:00 python discord discord.py

问题描述

基本上我正在做一个测验,我希望能够搜索答案并确定哪条消息只包含艺术家,哪条消息只包含歌曲名称,以及哪条消息同时显示它们.我已经制作了 3 个检查函数来显示这一点,但是我希望所有 3 个 wait_for_message 语句并排运行.关于如何解决这个问题的任何想法?

Basically I am making a quiz and I want to be able to search through the answers and determine which message only has the artist in, which message only has the song name in, and which message says them both. I've made 3 check functions to show this however I want all 3 wait_for_message statements to run side by side. Any ideas on how this could be remedied?

await client.say("What is the song name and artist?")
def check1(msg):
    return name in msg.content.upper() and artist not in msg.content.upper()
def check2(msg):
    return artist in msg.content.upper() and name not in msg.content.upper()
def check3(msg):
    return name in msg.content.upper() and artist in msg.content.upper()
msg1 = await client.wait_for_message(timeout=10, check=check1)
msg2 = await client.wait_for_message(timeout=10, check=check2)
msg3 = await client.wait_for_message(timeout=20, check=check3)
if msg3 is not None:
   await client.say("@{} got both of them right! It was indeed {} by {}".format(msg3.author, toString(name), 
                                                                                     toString(artist)))
elif msg1 is not None and msg2 is not None:
        await client.say("@{} got the song name and @{} got the artist name! It was indeed {} by {}".format(msg1.author, 
                                                                           msg2.author, toString(name), toString(artist)))
elif msg1 is not None and msg2 is None:
        await client.say("@{} got the song name but no one got the artist! It was {} by {}".format(msg1.author,
                                                                                       toString(name), toString(artist)))
elif msg1 is None and msg2 is not None:
        await client.say("@{} got the artist name but no one got the song name! It was {} by {}".format(msg2.author,
                                                                                       toString(name), toString(artist)))
elif msg1 is None and msg2 is None and msg3 is None:
        await client.say("No one got it! It was {} by {}! Better luck next time".format(toString(name), toString(artist)))


解决方案

你要找的代码是asyncio.gather.这让您可以同时运行多个协程并等待所有方法返回.

The code you are looking for is asyncio.gather. This lets you run multiple coroutines at the same time and wait until all methods are returned.

gather 的返回列表是按照输入的顺序,而不是按照任务完成的顺序.

The return list from gather is in the order of the inputs, not in the order of task completion.

ret = await asyncio.gather(
    client.wait_for_message(timeout=10, check=check1),
    client.wait_for_message(timeout=10, check=check2),
    client.wait_for_message(timeout=10, check=check3)
)

msg1, msg2, msg3 = *ret
# msg1 has the name
# msg2 has the artist
# msg3 has both

由于 discord.py 的重写版本有 client.wait_for 抛出错误而不是返回 None,你可以这样做.

Since the rewrite version of discord.py has client.wait_for throw an error instead of returning None, you can instead do this.

ret = await asyncio.gather(
    client.wait_for("message", timeout=10, check=check1),
    client.wait_for("message", timeout=10, check=check2),
    client.wait_for("message", timeout=10, check=check3),
    return_exceptions = True
)

# Test for errors
ret = [r if not isinstance(r, Exception) else None for r in ret]
msg1, msg2, msg3 = *ret

相关文章