Executing a function (with parameter) every X seconds in python

I want to run code that runs a function with a parameter (e.g. greet (h)) every 5 seconds. I tried to use streams, but that didn't work. It is executed only once. See code below and errors:

import threading oh_hi = "Hi guys" def greeting(hello): print "%s" % hello threading.Timer(1, greeting(oh_hi)).start() 

The error shown below:

 > >>> ================================ RESTART > ================================ > >>> Hi guys > >>> Exception in thread Thread-1: Traceback (most recent call last): > File "C:\Python27\lib\threading.py", > line 530, in __bootstrap_inner > self.run() File "C:\Python27\lib\threading.py", line > 734, in run > self.function(*self.args, **self.kwargs) TypeError: 'NoneType' object is not callable 

Please help.

thanks

+4
source share
4 answers

As others have noted, the error is that you are not passing the correct arguments to the threading.Timer() method. A fix that will run your function once, after 5 seconds. There are several ways to make it repeat.

The object-oriented approach should be to get a new subclass of threading.Thread . Although you could create one that does exactly what you want - namely print "%s" % hello - it’s a little harder to create a more general, parameterized subclass that will call the function passed to it at the time of its creation (just like threading.Timer() ). This is shown below:
 import threading import time class RepeatEvery(threading.Thread): def __init__(self, interval, func, *args, **kwargs): threading.Thread.__init__(self) self.interval = interval # seconds between calls self.func = func # function to call self.args = args # optional positional argument(s) for call self.kwargs = kwargs # optional keyword argument(s) for call self.runable = True def run(self): while self.runable: self.func(*self.args, **self.kwargs) time.sleep(self.interval) def stop(self): self.runable = False def greeting(hello): print hello thread = RepeatEvery(3, greeting, "Hi guys") print "starting" thread.start() thread.join(21) # allow thread to execute a while... thread.stop() print 'stopped' 

Output:

 # starting # Hi guys # Hi guys # Hi guys # Hi guys # Hi guys # Hi guys # Hi guys # stopped 

In addition to overriding the basic methods of threading.Thread class __init__() and run() , a stop() method has been added, which allows you to stop the thread if desired. I also simplified print "%s" % hello in your greeting() function only print hello .

+4
source

You need to pass the parameter oh_hi as the parameter itself for threading.Timer ... as indicated in the documentation ...

threading.Timer(interval, function, args=[], kwargs={})

To fix this, you would do ...

 import threading def greeting(hello): print "%s" % hello if __name__ == "__main__": oh_hi = "Hi guys" threading.Timer(1, greeting, args=(oh_hi,)).start() 
+3
source
 import time def greeting(hello): print "%s" % hello while True: greeting(oh_hi) time.sleep(5) 

If you want to use threading.Timer , keep in mind that you need to pass the parameter this way (see the docs ):

 threading.Timer(1, greeting, (oh_hi,)).start() 

The problem with your code is that greeting(oh_hi) is evaluated when the Timer object is created. The function is executed, but has no return value, and None becomes the second argument to Timer , which, of course, complains that None cannot be called.

0
source
 threading.Timer(1, greeting(oh_hi)).start() 

need a function as a second parameter. Your code gives it None (return value of the greeting(hello) function. You should use:

 threading.Timer(1, greeting).start() 

which, however, ignores the oh_hi parameter.

Reading the documentation involves:

 threading.Timer(1, greeting, args=[oh_hi]).start() 
0
source

Source: https://habr.com/ru/post/1346883/


All Articles