Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Improve current implementation of a setInterval

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

like image 875
user3234209 Avatar asked Mar 19 '14 06:03

user3234209


People also ask

What is the use of setInterval?

Definition and Usage. The setInterval() method calls a function or evaluates an expression at specified intervals (in milliseconds). The setInterval() method will continue calling the function until clearInterval() is called, or the window is closed. The ID value returned by setInterval() is used as the parameter for the clearInterval()...

What are The setInterval() and setTimeout() parameters?

These two parameters are the arguments that will be passed to the function (here, greet () function) that is defined inside the setInterval () method. Note: If you only need to execute a function one time, it's better to use the setTimeout () method.

What are the two parameters passed to The setInterval() method?

In the above program, two parameters John and Doe are passed to the setInterval () method. These two parameters are the arguments that will be passed to the function (here, greet () function) that is defined inside the setInterval () method.

How to use recursion with setInterval() method?

Recursion with setInterval () method: Interval time chosen includes time taken to execute the given part of code user wants to run. For e.g., let us say, code takes 60 milliseconds to run, hence the rest 40 milliseconds will end up as an interval. Here, once this code is executed, after 3 milliseconds, text color will change to orange.


1 Answers

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?

like image 127
jfs Avatar answered Oct 19 '22 12:10

jfs