What is the best way to repeatedly execute a function every x seconds? [closed] What is the best way to repeatedly execute a function every x seconds? [closed] python python

What is the best way to repeatedly execute a function every x seconds? [closed]


If your program doesn't have a event loop already, use the sched module, which implements a general purpose event scheduler.

import sched, times = sched.scheduler(time.time, time.sleep)def do_something(sc):     print("Doing stuff...")    # do your stuff    s.enter(60, 1, do_something, (sc,))s.enter(60, 1, do_something, (s,))s.run()

If you're already using an event loop library like asyncio, trio, tkinter, PyQt5, gobject, kivy, and many others - just schedule the task using your existing event loop library's methods, instead.


Lock your time loop to the system clock like this:

import timestarttime = time.time()while True:    print "tick"    time.sleep(60.0 - ((time.time() - starttime) % 60.0))


If you want a non-blocking way to execute your function periodically, instead of a blocking infinite loop I'd use a threaded timer. This way your code can keep running and perform other tasks and still have your function called every n seconds. I use this technique a lot for printing progress info on long, CPU/Disk/Network intensive tasks.

Here's the code I've posted in a similar question, with start() and stop() control:

from threading import Timerclass RepeatedTimer(object):    def __init__(self, interval, function, *args, **kwargs):        self._timer     = None        self.interval   = interval        self.function   = function        self.args       = args        self.kwargs     = kwargs        self.is_running = False        self.start()    def _run(self):        self.is_running = False        self.start()        self.function(*self.args, **self.kwargs)    def start(self):        if not self.is_running:            self._timer = Timer(self.interval, self._run)            self._timer.start()            self.is_running = True    def stop(self):        self._timer.cancel()        self.is_running = False

Usage:

from time import sleepdef hello(name):    print "Hello %s!" % nameprint "starting..."rt = RepeatedTimer(1, hello, "World") # it auto-starts, no need of rt.start()try:    sleep(5) # your long-running job goes here...finally:    rt.stop() # better in a try/finally block to make sure the program ends!

Features:

  • Standard library only, no external dependencies
  • start() and stop() are safe to call multiple times even if the timer has already started/stopped
  • function to be called can have positional and named arguments
  • You can change interval anytime, it will be effective after next run. Same for args, kwargs and even function!