Улучшение текущей реализации питона setInterval

Я пытался выяснить, как сделать setInterval, который отменяет в python, не создавая для этого нового класса, я понял, как, но теперь мне интересно, есть ли лучший способ сделать это.

Код ниже, кажется, работает нормально, но я не проверил его полностью.

import threading
def setInterval(func, sec):
    def inner():
        while function.isAlive():
            func()
            time.sleep(sec)
    function = type("setInterval", (), {}) # not really a function I guess
    function.isAlive = lambda: function.vars["isAlive"]
    function.vars = {"isAlive": True}
    function.cancel = lambda: function.vars.update({"isAlive": False})
    thread = threading.Timer(sec, inner)
    thread.setDaemon(True)
    thread.start()
    return function
interval = setInterval(lambda: print("Hello, World"), 60) # will print Hello, World every 60 seconds
# 3 minutes later
interval.cancel() # it will stop printing Hello, World 

Есть ли способ сделать выше, не делая выделенный класс, который наследует от threading.Thread или используя type("setInterval", (), {})? Или я застрял в выборе между выделенным классом или продолжаю использовать type

1 ответ

Решение

Для повторного вызова функции с interval секунд между звонками и возможностью отмены будущих звонков:

from threading import Event, Thread

def call_repeatedly(interval, func, *args):
    stopped = Event()
    def loop():
        while not stopped.wait(interval): # the first call is in `interval` secs
            func(*args)
    Thread(target=loop).start()    
    return stopped.set

Пример:

cancel_future_calls = call_repeatedly(60, print, "Hello, World")
# ...
cancel_future_calls() 

Примечание: эта версия ждет interval секунд после каждого звонка, независимо от того, как долго func(*args) принимает. Если меткообразные метки желательны, то выполнение может быть заблокировано с помощью timer(): stopped.wait(interval) можно заменить на stopped.wait(interval - timer() % interval) где timer() определяет текущее время (оно может быть относительным) в секундах, например, time.time(), См. Каков наилучший способ повторного выполнения функции каждые x секунд в Python?

Другие вопросы по тегам