Улучшить текущую реализацию setInterval python
Я пытался выяснить, как сделать 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?