Перезарядка в операторе if - PullRequest
0 голосов
/ 28 января 2019

Я пишу довольно простой Twitch Chatbot в Python, и у меня есть все мои «команды», выполняемые в операторах if (в основном, если чатбот видит что-то в чате, он активируется).

Тем не менее, я хочу добавить время восстановления около 3 секунд или действительно количество времени на команду (или оператор if), чтобы я мог настроить его в зависимости.Чтобы сделать это, я попробовал это (псевдокод)

if command is seen in chat
    newtimestamp = create timestamp at now
    if (newtimestamp - previoustimestamp) > 30
        execute the command
        make (previoustimestamp)
    else
        return

, но это не сработало, потому что, очевидно, он не обнаруживает (предыдущую временную метку) при первом запуске, так как он еще не объявлен, но когда вы объявляете его, он объявляет это каждый раз при запуске команды.

Так есть ли способ сделать объявление только один раз в начале оператора if, а затем игнорировать его впоследствии каждый раз?Или есть другие идеи?Я все еще довольно начинающий программист, поэтому я прошу прощения.

Вот пример кода, для которого я хотел бы получить перезарядку, что-то довольно простое

if "!redb match" in message:    
   x = str(randint(1, 100))
   realmessage = message.replace('!redb ship ', '')
   array = realmessage.split(' ')
   person1 = array[0]
   person2 = array[1]
   if ((9 - 2) > 5):
      sendMessage(s, person1 + " and " + person2 + "have a " + x + "% love compatibility <3")           
   else:
      break

Ответы [ 3 ]

0 голосов
/ 28 января 2019

Я бы использовал словарь для отметок времени, получая доступ к нему как previous_timestamp = command_timestamps.get('!redb match', 0).Это даст вам сохраненную временную метку, если она находится в словаре, и 0 (1 января 1970 года, если вы используете time.time() для своих временных меток, что, как мы надеемся, достаточно далеко в прошлом, чтобы не запутать ни одну из вашихкулдауны).

0 голосов
/ 28 января 2019

Вы можете написать декоратор для функции, которая хранит последний раз, когда она была вызвана, и вернуть None, если это было слишком близко к этому моменту

from functools import wraps
from datetime import datetime, timedelta


def cooldown(*delta_args, **delta_kwargs):
    delta = timedelta(*delta_args, **delta_kwargs)
    def decorator(func):
        last_called = None
        @wraps(func)
        def wrapper(*args, **kwargs):
            nonlocal last_called
            now = datetime.now()
            if last_called and (now - last_called < delta):
                return
            last_called = now
            return func(*args, **kwargs)
        return wrapper
    return decorator

@cooldown(seconds=5)
def foo():
    print("Run")

foo() # Run
time.sleep(1)
foo()
time.sleep(4) 
foo() # Run

Аргументы для cooldown отправляются вtimedelta, поэтому вам следует прочитать документацию подробнее об этих объектах

0 голосов
/ 28 января 2019

Вы можете использовать time.sleep(3) для ожидания 3 секунд, если, например, срабатывает определенное условие.Это приостановит выполнение на 3 секунды.

Редактировать: так как вы хотите, чтобы эти операторы имели собственные перезарядки, вы можете попробовать поместить это в цикл управления, который немного сложнее

cooldowns_dict = {"trigger_1": 0, "trigger_2":0}

while(True):
    loop_start = time.time()
    if ("!redb match" in message) and cooldowns_dict["trigger_1"] <= 0:
        # Send message etc.
        cooldowns_dict["trigger_1"] = 3    # Set a 3 second cooldown

    time.sleep(0.1)    # Just to stop this looping too fast
    loop_end = time.time()
    # update the cooldowns
    for key, value in cooldowns_dict.items():
        if value > 0:
            cooldowns_dict[key] -= (loop_end - loop_start)
        else:
            cooldowns_dict[key] = 0
...