I was trying to figure out how to make a setInterval that cancels in python without making an entire new class to do that, I figured out how but now I’m wondering if there is a better way to do it.
The code below seems to work fine, but I have not thoroughly tested it.
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
Is there a way to do the above without making a dedicated class that inherits from threading.Thread or using the type("setInterval", (), {}) ? Or am I stuck in deciding between making a dedicated class or continue to use type
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
To call a function repeatedly with interval seconds between the calls and the ability to cancel future calls:
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
Example:
cancel_future_calls = call_repeatedly(60, print, "Hello, World") # ... cancel_future_calls()
Note: this version waits around interval seconds after each call no matter how long func(*args) takes. If metronome-like ticks are desired then the execution could be locked with a timer(): stopped.wait(interval) could be replaced with stopped.wait(interval - timer() % interval) where timer() defines the current time (it may be relative) in seconds e.g., time.time(). See What is the best way to repeatedly execute a function every x seconds in Python?
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0