I tried some with the theme.
First and foremost, you can use time.sleep
to delay the specified time processing as follows:
import time
def hello(target):
print("Hello {}".format(target))
time.sleep(3)
hello("World")
However, this delays everything after time.sleep
. How can I delay a specific process like setTimeout?
You can do this with threading.Timer.
from threading import Timer
def hello(target):
print("Hello {}".format(target))
timer = Timer(3, hello, ("World", ))
timer.start()
You can also cancel in the middle as follows.
timer.cancel()
This method spawns a thread for each Timer call. It's a bit inefficient and different from the JavaScript setTimeout method.
In JavaScript, the event loop handles various events in a single thread. There is a way to do that in Python 3.4 and later. This is a method using asyncio, a package that comes standard with Python 3.4 or later. Like JavaScript, it uses an event loop. However, in JavaScript, the event loop was implicit, but in asyncio you need to do it explicitly.
The following two are code examples. [^ 1] [^ 2] [^ 3]
I posted an example of using a different API, which is almost the same as what I am doing. The call_later version raises an event that executes the specified function after (or later) the number of seconds specified in asyncio.call_later. The coroutine version [^ 4] wraps with a coroutine that calls the original function after returning the specified number of seconds control called wrap_with_delay to the event loop. In this code, the call_later version is simpler, but when multiple processes are chained, the coroutine version that can be written like synchronous processing is easier to understand.
import asyncio
def hello(target, loop=None):
print("Hello {}".format(target))
if loop is None:
loop = asyncio.get_event_loop()
loop.stop() #Added processing to stop the event loop and return control
loop = asyncio.get_event_loop() #Get default event loop
loop.call_later(3, hello, "World")
loop.run_forever() #Event loop start. It will not come back unless you explicitly stop it.
# loop.close()
import asyncio
#With async, it's a coroutine instead of a normal function
async def wrap_with_delay(sec, func, *args):
await asyncio.sleep(sec) #Return control to the event loop with await
func(*args)
def hello(target, loop=None):
print("Hello {}".format(target))
if loop is None:
loop = asyncio.get_event_loop()
loop.stop() #Added processing to stop the event loop and return control
loop = asyncio.get_event_loop()
asyncio.ensure_future(wrap_with_delay(3, hello, "World"))
loop.run_forever()
# loop.close()
[^ 1]: Originally, the event loop is a mechanism for time-dividing multiple processes and executing them in parallel, so it is not usual to put only delayed execution in the event loop as in this example.
[^ 2]: Execution does not end if you do not rotate the event loop, so we have added a process to stop the loop so that you can easily try it. This is extra processing from the perspective of comparison with other methods.
[^ 3]: If you close the default event loop, asyncio.get_event_loop will fail after that, so I commented it out considering execution with jupyter notebook.
[^ 4]: This code itself works on Python 3.5 or later, but with a few changes it can also be run on Python 3.4
Recommended Posts