我试图让测试不和谐机器人的状态每十秒钟在两条消息之间发生变化。我需要在状态消息更改时执行脚本的其余部分,但每当我尝试使其工作时,错误就会一直弹出。我的脚本中有线程,但我不完全确定在这种情况下如何使用它。
@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)
答案 0 :(得分:8)
不幸的是,线程和asyncio不能很好地融合在一起。你需要跳过额外的箍来等待线程内的协同程序。最简单的解决方案是不使用线程。
你要做的是等待一段时间,然后运行一个协程。这可以通过后台任务(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。
答案 1 :(得分:0)
见:
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附带内置后台任务功能
答案 2 :(得分:0)
https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html版本1.1.0引入了discord.py,其目的是使诸如您描述的背景任务之类的背景任务变得更容易,并且在存在连接的情况下处理潜在的复杂逻辑,即重新连接至不和谐问题。
以下是使用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")