让不和谐机器人每 10 秒改变一次播放状态

2022-01-15 00:00:00 python python-3.x python-3.6 discord.py

问题描述

我正在尝试让测试不和谐机器人的状态每十秒在两条消息之间更改一次.我需要在状态消息更改时执行脚本的其余部分,但是每当我尝试使其工作时都会弹出错误.我的脚本中有线程,但我不完全确定在这种情况下如何使用它.

I'm trying to make the status for a test discord bot change between two messages every ten seconds. I need the rest of the script to execute while the status message changes, but an error keeps popping up whenever I try to make it work. There's threading in my script, but I'm not entirely sure how to use it in this circumstance.

@test_bot.event
async def on_ready():
    print('Logged in as')
    print(test_bot.user.name)
    print(test_bot.user.id)
    print('------')
    await change_playing()


@test_bot.event
async def change_playing():
    threading.Timer(10, change_playing).start()
    await test_bot.change_presence(game=discord.Game(name='Currently on ' + str(len(test_bot.servers)) +
                                                          ' servers'))
    threading.Timer(10, change_playing).start()
    await test_bot.change_presence(game=discord.Game(name='Say test.help'))

错误信息如下:

C:PythonPython36-32lib	hreading.py:1182: RuntimeWarning: coroutine 'change_playing' was never awaited
  self.function(*self.args, **self.kwargs)


解决方案

不幸的是,线程和异步不能很好地结合在一起.您需要跳过额外的障碍来等待线程内的协程.最简单的解决方案是不使用线程.

Threading and asyncio don't play nice together unfortunately. You need to jump through extra hoops to await coroutines inside threads. The simplest solution is to just not use threading.

您要做的是等待一段时间,然后运行协程.这可以通过后台任务来完成(example)

What you are trying to do is wait a duration and then run a coroutine. This can be done with a background task (example)

async def status_task():
    while True:
        await test_bot.change_presence(...)
        await asyncio.sleep(10)
        await test_bot.change_presence(...)
        await asyncio.sleep(10)

@test_bot.event
async def on_ready():
    ...
    bot.loop.create_task(status_task())

您不能使用 time.sleep(),因为这会阻止机器人的执行.asyncio.sleep() 虽然和其他所有东西一样是一个协程,因此它是非阻塞的.

You cannot use time.sleep() as this will block the execution of the bot. asyncio.sleep() though is a coroutine like everything else and as such is non-blocking.

最后,@client.event 装饰器只能用于机器人识别为 事件.比如 on_ready 和 on_message.

Lastly, the @client.event decorator should only be used on functions the bot recognises as events. Such as on_ready and on_message.

相关文章