如何使用计划库运行异步函数?

新手上路,请多包涵

我正在使用 discord.py rewrite 编写一个 discord bot,我想在每天的特定时间运行一个函数。我完全没有使用异步函数的经验,而且我不知道如何在不使用“等待”的情况下运行异步函数。这只是我的一段代码,这就是为什么有些东西可能没有定义的原因。

 async def send_channel():
    try:
        await active_channel.send('daily text here')
    except Exception:
        active_channel_id = None
        active_channel = None

async def timer():
    while True:
        schedule.run_pending()
        await asyncio.sleep(3)
        schedule.every().day.at("21:57").do(await send_channel())

@bot.event
async def on_ready():
    print("Logged in as")
    print(bot.user.name)
    print(bot.user.id)
    print("------")

    bot.loop.create_task(timer())

使用 schedule.every().day.at("00:00").do() 函数,当我将 await send_channel() 放入 .do() 的参数时出现此错误:

self.job_func = functools.partial(job_func, *args, **kwargs) 类型错误:第一个参数必须是可调用的

但是当我不使用 await,而我只有 send_channel() 作为参数时,我得到这个错误:

RuntimeWarning:从未等待协程“send_channel”

我不是很擅长编程,所以如果有人可以尝试为我简化它,那就太棒了。

谢谢

原文由 Michael Leonard 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 475
1 个回答

discord.py 中对此的内置解决方案是使用 discord.ext.tasks 扩展。这使您可以注册一个以特定时间间隔重复调用的任务。当机器人开始时,我们将循环的开始延迟到目标时间,然后每 24 小时运行一次任务:

 import asyncio
from discord.ext import commands, tasks
from datetime import datetime, timedelta

bot = commands.Bot("!")

@tasks.loop(hours=24)
async def my_task():
    ...

@my_task.before_loop
async def before_my_task():
    hour = 21
    minute = 57
    await bot.wait_until_ready()
    now = datetime.now()
    future = datetime.datetime(now.year, now.month, now.day, hour, minute)
    if now.hour >= hour and now.minute > minute:
        future += timedelta(days=1)
    await asyncio.sleep((future-now).seconds)

my_task.start()

原文由 Patrick Haugh 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题