【问题标题】:threading.Timer alternative for coroutinesthreading.Timer 协程的替代方案
【发布时间】:2021-04-08 23:32:53
【问题描述】:

我正在创建一个不和谐的机器人,我想知道是否有任何第三方库可以与 threading.Timer 做同样的事情,但支持 Discord.client.send 的协程。

@client.command(aliases = ['Timer'])
async def timer(ctx, secs, *message):
    await ctx.send(f"Your timer {message} started, and it is gonna take {secs}secs to stop.")

    async def stop_timer():
        await ctx.send(f'Your timer: {message} is over, it took {secs} secs.')

    def timer_over():
        asyncio.run(stop_timer())
        
    simpleTimer = threading.Timer(int(secs), timer_over)
    simpleTimer.start()

我的代码在那里,我正在寻找一个需要几秒钟的函数,然后在几秒钟后该函数返回一个协程。有点像闹钟。

【问题讨论】:

    标签: python discord discord.py coroutine


    【解决方案1】:

    从discord.ext查看tasks:

    from discord.ext import tasks
    
    @tasks.loop(seconds=30)
    async def my_loop(messageable):
        await messageable.send("Here's some message!")
    
    @bot.command()
    async def startloop(ctx):
        my_loop.start(messageable=ctx)
    

    这将每 30 秒将Here's some message! 发送到您提供给它的任何消息对象。


    参考资料:

    【讨论】:

    • tasks 每隔 n 秒重复一次消息,我想要的是只做一次,像警报一样,像 threading.Timer
    • @Zac 你可以在装饰循环时使用count kwarg。它将指定您希望循环实际循环多少次,即@tasks.loop(count=1, seconds=30) 只会让它运行一次。
    • 当我使用count = 1时,它只会在我使用命令并停止时立即发送一次消息。
    • 有没有办法使用count = 2 并且第一个计数不发送任何消息?
    • @Zac 你可以使用await asyncio.sleep(x) 睡眠一段时间然后做点什么吗?如果有任何帮助,它就是 time.sleep() 的异步版本。还有Client.wait_for(),如果这就是你所追求的。
    【解决方案2】:

    感谢@Diggy 提及asyncio.sleep

    这是符合我想要并且有效的代码:

    @client.command(aliases = ['Timer'])
    async def timer(ctx, secs, *message):
        globalsecs = secs
        await ctx.send(f"The timer {message} started and it is going to take {secs} secs to be over.")
        await asyncio.sleep(int(secs))
        await send_message(message = f'Your timer:{message} is over, it took {secs}secs.', ctx = ctx)
        
    async def send_message(ctx, message):
        await ctx.send(message)
    

    【讨论】:

      【解决方案3】:

      这是一个非常简单的示例(对于您的计时器示例):

      @client.command(aliases = ['Timer'])
      async def timer(ctx, secs, *message):
          if secs < 1:
              await ctx.send("You can't give seconds lower than 1!")
          else:
              timer = await ctx.send(f"Your timer {message} started, and it is gonna take {secs}secs to stop.")
              while True:
                  if secs > 0:
                      await asyncio.sleep(1)
                      secs -= 1
                      await timer.edit(content=f"Your timer {message} started, and it is gonna take {secs}secs to stop.")
                  else:
                      await ctx.send(f'Your timer: {message} is over, it took {secs} secs.')
      

      也许这对你有帮助..

      【讨论】:

        猜你喜欢
        • 2021-07-31
        • 2018-03-09
        • 1970-01-01
        • 2021-06-13
        • 2020-02-09
        • 2022-09-26
        • 1970-01-01
        • 2011-11-10
        • 2012-03-09
        相关资源
        最近更新 更多