Solving problem is about exposing yourself to as many situations as possible like Run certain code every n seconds [duplicate] and practice these strategies over and over. With time, it becomes second nature and a natural way you approach any problems in general. Big or small, always start with a plan, use other strategies mentioned here till you are confident and ready to code the solution.
In this post, my aim is to share an overview the topic about Run certain code every n seconds [duplicate], which can be followed any time. Take easy to follow this discuss.
Is there a way to, for example, print
Hello World! every n seconds?
For example, the program would go through whatever code I had, then once it had been 5 seconds (with
time.sleep()) it would execute that code. I would be using this to update a file though, not print Hello World.
startrepeat("print('Hello World')", .01) # Repeats print('Hello World') ever .01 seconds for i in range(5): print(i) >> Hello World! >> 0 >> 1 >> 2 >> Hello World! >> 3 >> Hello World! >> 4
import threading def printit(): threading.Timer(5.0, printit).start() print "Hello, World!" printit() # continue with the rest of your code
My humble take on the subject, a generalization of Alex Martelli’s answer, with start() and stop() control:
from threading import Timer class 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
from time import sleep def hello(name): print "Hello %s!" % name print "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!
- Standard library only, no external dependencies
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
intervalanytime, it will be effective after next run. Same for
def update(): import time while True: print 'Hello World!' time.sleep(5)
That’ll run as a function. The
while True: makes it run forever. You can always take it out of the function if you need.
Save yourself a schizophrenic episode and use the Advanced Python scheduler:
The code is so simple:
from apscheduler.scheduler import Scheduler sched = Scheduler() sched.start() def some_job(): print "Every 10 seconds" sched.add_interval_job(some_job, seconds = 10) .... sched.shutdown()
Here is a simple example compatible with APScheduler 3.00+:
# note that there are many other schedulers available from apscheduler.schedulers.background import BackgroundScheduler sched = BackgroundScheduler() def some_job(): print('Every 10 seconds') # seconds can be replaced with minutes, hours, or days sched.add_job(some_job, 'interval', seconds=10) sched.start() ... sched.shutdown()
Alternatively, you can use the following. Unlike many of the alternatives, this timer will execute the desired code every n seconds exactly (irrespective of the time it takes for the code to execute). So this is a great option if you cannot afford any drift.
import time from threading import Event, Thread class RepeatedTimer: """Repeat `function` every `interval` seconds.""" def __init__(self, interval, function, *args, **kwargs): self.interval = interval self.function = function self.args = args self.kwargs = kwargs self.start = time.time() self.event = Event() self.thread = Thread(target=self._target) self.thread.start() def _target(self): while not self.event.wait(self._time): self.function(*self.args, **self.kwargs) def _time(self): return self.interval - ((time.time() - self.start) % self.interval) def stop(self): self.event.set() self.thread.join() # start timer timer = RepeatedTimer(10, print, 'Hello world') # stop timer timer.stop()
Here’s a version that doesn’t create a new thread every
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
The event is used to stop the repetitions:
cancel_future_calls = call_repeatedly(5, print, "Hello, World") # do something else here... cancel_future_calls() # stop future calls
You can start a separate thread whose sole duty is to count for 5 seconds, update the file, repeat. You wouldn’t want this separate thread to interfere with your main thread.