this is rather complicated, but a simple idea is to start a timer thread and cancel it if the function is called again and start another timer thread.
now we need somewhere to store this timer ... so a dictionary should suffice, and to allow the user to choose the delay, we will just do a double wrap of functions.
from threading import Timer
from functools import wraps
import time
functions_store = {}
def main_decorator(interval):
def sub_decorator(fun):
function_id = id(fun) # since no two objects have the same id
@wraps(fun)
def new_fun(*args,**kwargs):
if function_id in functions_store:
functions_store[function_id].cancel() # cancel old timer
new_timer = Timer(interval,fun,args=args,kwargs=kwargs) # make new timer
functions_store[function_id] = new_timer # store timer to stop it later
new_timer.start()
return new_fun
return sub_decorator
@main_decorator(1) # must be called again before 1 second passes.
def func_to_run():
print("hi")
func_to_run()
time.sleep(0.5)
func_to_run()
the word "hi" will be printed after 1.5 seconds instead of 1 second because we called the function again before it fired the first time.