In JavaScript I am used to being able to call functions to be executed at a later time, like this
function foo() {
alert('bar');
}
setTimeout(foo, 1000);
This does not block the execution of other code.
I do not know how to achieve something similar in Python. I can use sleep
import time
def foo():
print('bar')
time.sleep(1)
foo()
but this will block the execution of other code. (Actually in my case blocking Python would not be a problem in itself, but I would not be able to unit test the method.)
I know threads are designed for out-of-sync execution, but I was wondering whether something easier, similar to setTimeout
or setInterval
exists.
You want a
Timer
object from thethreading
module.If you want to repeat, here's a simple solution: instead of using
Timer
, just useThread
but pass it a function that works somewhat like this:This won't do infinite loops because that could result in a thread that won't die and other unpleasant behavior if not done right. A more sophisticated approach might use an
Event
-based approach, like this one.JavaScript can do this because it runs things in an event loop. This can be done in Python through use of an event loop such as Twisted, or via a toolkit such as GLib or Qt.
The problem is that your normal python script doesn't run in a framework. The script gets called and is in control of the main loop. With JavaScript, all the scripts that runs on your page runs in a framework and it is the framework that invokes your method when the timeout elapses.
I haven't used pyQt myself (only C++ Qt), but you can set a timer on any QObject using startTimer(). When the timer elapse, a callback on your method is invoked. You can also use QTimer and connect the timeout signal to an arbitrary slot. This is possible because Qt runs an event loop that can call your method at a later stage.
To execute a function after a delay or to repeat a function in given number of seconds using an event-loop (no threads), you could:
Tkinter
Output
Gtk
Output
Twisted
Output
Asyncio
Python 3.4 introduces new provisional API for asynchronous IO --
asyncio
module:Output
Note: there is a slight difference in the interface and behavior between these approaches.
Sorry, I can't post more than 2 links, so for more information please check PEP 380 and most importantly the documentation of asyncio.
asyncio is the preferred solution to this kind of question unless you insist on threading or multiprocessing. It is designed and implemented by GvR under the name "Tulip". It has been introduced by GvR on PyCon 2013 with the intention to be the one event-loop to rule (and standardize) all event-loops (like the ones in twisted, gevent, etc.) and make them compatible with each other. asyncio has been mentioned before, but the true power of asyncio is unleashed with yield from.
================
Asynchronous callbacks like Javascript's
setTimeout
require an event-driven architecture.Asynchronous frameworks for Python like the popular twisted have
CallLater
which does what you want, but it means adopting the event-driven architecture in your application.Another alternative is to use threads and to sleep in a thread. Python providers a timer to make the waiting part easy. However, when your thread awakes and your function executes, it is in a separate thread and must do whatever it does in a thread-safe manner.