【问题标题】:Making a discord bot change playing status every 10 seconds让不和谐机器人每 10 秒改变一次播放状态
【发布时间】:2018-02-26 07:21:43
【问题描述】:

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

@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:\Python\Python36-32\lib\threading.py:1182: RuntimeWarning: coroutine 'change_playing' was never awaited
  self.function(*self.args, **self.kwargs)

【问题讨论】:

  • 请编辑问题以包含实际的错误消息。
  • 已编辑,感谢您指出这一点。

标签: python python-3.x python-3.6 discord.py


【解决方案1】:

1.1.0 版引入了discord.ext.tasks,旨在使您描述的后台任务更容易,以及在出现连接问题时处理重新连接到不和谐的潜在复杂逻辑。

这是使用tasks 的任务示例:

from discord.ext import commands, tasks
from commands import Bot
from tasks import loop
from asyncio import sleep

bot = Bot("!")

@loop(seconds=10)
async def name_change():
    await bot.change_presence(...)
    await sleep(10)
    await bot.change_presence(...)

name_change.before_loop(bot.wait_until_ready())    
name_change.start()
bot.run("TOKEN")

【讨论】:

    【解决方案2】:

    看这个:

    https://github.com/Rapptz/discord.py/blob/master/examples/background_task.py

    import discord
    import asyncio
    client = discord.Client()
    async def my_background_task():
        await client.wait_until_ready()
        counter = 0
        channel = discord.Object(id='channel_id_here')
        while not client.is_closed:
            counter += 1
            await client.send_message(channel, counter)
            await asyncio.sleep(60) # task runs every 60 seconds
    @client.event
    async def on_ready():
        print('Logged in as')
        print(client.user.name)
        print(client.user.id)
        print('------')
    client.loop.create_task(my_background_task())
    client.run('token')
    

    Discord.py 带有内置的后台任务功能,

    【讨论】:

      【解决方案3】:

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

      您要做的是等待一段时间,然后运行协程。这可以通过后台任务完成 (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() 虽然和其他所有东西一样是一个协程,因此它是非阻塞的。

      最后,@client.event 装饰器只能用于机器人识别为events 的函数。比如 on_ready 和 on_message。

      【讨论】:

      • 这澄清了我也有很多其他问题,我上周开始学习 python 3,所以我没有意识到。
      猜你喜欢
      • 2021-06-10
      • 2021-01-13
      • 2018-12-13
      • 1970-01-01
      • 1970-01-01
      • 2013-05-22
      • 1970-01-01
      • 2021-04-27
      • 1970-01-01
      相关资源
      最近更新 更多