Log*_*man 6 python python-asyncio discord
我正在尝试创建一个 python discord bot,它将每 X 秒检查一次活跃成员,并根据他们的在线时间奖励成员。我正在使用 asyncio 来处理聊天命令,这一切正常。我的问题是找到一种方法,以异步方式每 X 秒安排一次对活动成员的检查
我已经阅读了 asnycio 文档,但这是我第一次使用它,而且我很难把头放在任务和循环以及协同例程等上。
@client.event
async def on_message(message):
# !gamble command
if message.content.startswith('!gamble'):
...code that works....
# !help command
elif message.content == '!help':
...code that works....
# !balance command
elif message.content == '!balance':
...code that works....
@client.event
async def on_ready():
print('Logged in as')
print(client.user.name)
print(client.user.id)
print('------')
# Do this every X seconds to give online users +1 points
async def periodic_task():
TODO
Run Code Online (Sandbox Code Playgroud)
我的目标是让机器人能够处理通过聊天给它的命令,同时每隔 X 秒触发一个与 Discord 服务器中的聊天命令或事件无关的功能。我知道如何让函数内部的代码实现我的目标,只是不知道如何触发它
如果您想确保执行时间不会导致间隔漂移,您可以使用 asyncio.gather。
import asyncio, time, random
start_time = time.time()
async def stuff():
await asyncio.sleep(random.random() * 3)
print(round(time.time() - start_time, 1), "Finished doing stuff")
async def do_stuff_periodically(interval, periodic_function):
while True:
print(round(time.time() - start_time, 1), "Starting periodic function")
await asyncio.gather(
asyncio.sleep(interval),
periodic_function(),
)
asyncio.run(do_stuff_periodically(5, stuff))
Run Code Online (Sandbox Code Playgroud)
然后输出变为:
0.0 Starting periodic function
0.5 Finished doing stuff
5.0 Starting periodic function
7.2 Finished doing stuff
10.0 Starting periodic function
10.1 Finished doing stuff
15.0 Starting periodic function
17.9 Finished doing stuff
Run Code Online (Sandbox Code Playgroud)
如您所见,所调用的周期函数的执行时间不会影响新间隔的开始时间。
async def do_stuff_every_x_seconds(timeout, stuff):
while True:
await asyncio.sleep(timeout)
await stuff()
Run Code Online (Sandbox Code Playgroud)
并将其添加到循环中。
task = asyncio.create_task(do_stuff_every_x_seconds(10, stuff))
Run Code Online (Sandbox Code Playgroud)
当你不想再这样做时,
task.cancel()
Run Code Online (Sandbox Code Playgroud)