Not much to say here, just a snippet to share.
def periodic(interval, times = -1): def outer_wrap(function): def wrap(*args, **kwargs): stop = threading.Event() def inner_wrap(): i = 0 while i != times and not stop.isSet(): stop.wait(interval) function(*args, **kwargs) i += 1 t = threading.Timer(0, inner_wrap) t.daemon = True t.start() return stop return wrap return outer_wrap