многопоточность.Альтернатива таймера для сопрограмм

#python #discord #discord.py #coroutine

#python #Discord #discord.py #сопрограмма

Вопрос:

Я создаю discord-бота, и я хотел бы знать, есть ли какие-либо сторонние библиотеки, которые делают то же самое, что и потоковая передача.Таймер, но с поддержкой сопрограмм для 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()
 

Мой код там, я ищу функцию, которая занимает несколько секунд, и после этих секунд функция возвращает сопрограмму. Вроде как сигнал тревоги.

Ответ №1:

Проверьте из tasks discord.ext :

 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)
 

Это будет отправляться Here's some message! на любой объект с возможностью отправки сообщений, который вы предоставляете ему каждые 30 секунд.


Ссылки:

  • ext.tasks
  • abc.Messageable — Это такие вещи, как текстовые каналы, пользователи и т.д. Вы можете увидеть, что наследуется от него в документах.
  • Loop.stop() — Остановка циклов
  • Loop.start() — Запуск циклов

Комментарии:

1. задачи повторяют сообщение каждые n секунд, я хочу сделать это только один раз, например, сигнал тревоги, например, потоковое. Таймер

2. @Zac Вы можете использовать count kwarg при оформлении цикла. В нем будет указано, сколько раз вы хотите, чтобы цикл фактически выполнялся, т. Е. @tasks.loop(count=1, seconds=30) Выполнялся бы только один раз.

3. когда я использую count = 1 его, просто отправляйте сообщение сразу один раз, когда я использую команду, и останавливается.

4. есть ли способ использовать count = 2 , и первый счетчик не отправляет никаких сообщений?

5. @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.')
 

Может быть, это вам поможет..