In pratica, uno Timer è probabilmente il modo più semplice per fare ciò che vuoi.
Questo codice farà il seguente:
- Dopo 1 secondo, esso stampa "arg1 arg2"
- Dopo 2 secondi, esso stampa "gufi Gufi Gufi"
===
from threading import Timer
def twoArgs(arg1,arg2):
print arg1
print arg2
print ""
def nArgs(*args):
for each in args:
print each
#arguments:
#how long to wait (in seconds),
#what function to call,
#what gets passed in
r = Timer(1.0, twoArgs, ("arg1","arg2"))
s = Timer(2.0, nArgs, ("OWLS","OWLS","OWLS"))
r.start()
s.start()
===
Il codice precedente molto probabilmente risolverà il tuo problema.
Ma! C'è un modo alternativo, che non usa il multithreading. Funziona molto più come Javascript, che è single-threaded.
Per questa versione a thread singolo, tutto ciò che dovete fare è memorizzare la funzione ei suoi argomenti in un oggetto, insieme al momento in cui la funzione deve essere eseguita.
Una volta che l'oggetto contiene la chiamata di funzione e il timeout, controllare periodicamente se la funzione è pronta per l'esecuzione.
Il modo giusto per fare ciò è creare un priority queue per memorizzare tutte le funzioni che vogliamo eseguire in futuro, come mostrato nel codice qui sotto.
Proprio come in Javascript, questo approccio non garantisce che la funzione verrà eseguita esattamente in tempo. Una funzione che richiede molto tempo per l'esecuzione ritarderà le funzioni dopo di essa. Ma garantisce che una funzione verrà eseguita non prima del rispetto al timeout.
Questo codice farà il seguente:
- Dopo 1 secondo, esso stampa "20"
- Dopo 2 secondi, viene stampato "132"
- Dopo 3 secondi, si chiude.
===
from datetime import datetime, timedelta
import heapq
# just holds a function, its arguments, and when we want it to execute.
class TimeoutFunction:
def __init__(self, function, timeout, *args):
self.function = function
self.args = args
self.startTime = datetime.now() + timedelta(0,0,0,timeout)
def execute(self):
self.function(*self.args)
# A "todo" list for all the TimeoutFunctions we want to execute in the future
# They are sorted in the order they should be executed, thanks to heapq
class TodoList:
def __init__(self):
self.todo = []
def addToList(self, tFunction):
heapq.heappush(self.todo, (tFunction.startTime, tFunction))
def executeReadyFunctions(self):
if len(self.todo) > 0:
tFunction = heapq.heappop(self.todo)[1]
while tFunction and datetime.now() > tFunction.startTime:
#execute all the functions that are ready
tFunction.execute()
if len(self.todo) > 0:
tFunction = heapq.heappop(self.todo)[1]
else:
tFunction = None
if tFunction:
#this one's not ready yet, push it back on
heapq.heappush(self.todo, (tFunction.startTime, tFunction))
def singleArgFunction(x):
print str(x)
def multiArgFunction(x, y):
#Demonstration of passing multiple-argument functions
print str(x*y)
# Make some TimeoutFunction objects
# timeout is in milliseconds
a = TimeoutFunction(singleArgFunction, 1000, 20)
b = TimeoutFunction(multiArgFunction, 2000, *(11,12))
c = TimeoutFunction(quit, 3000, None)
todoList = TodoList()
todoList.addToList(a)
todoList.addToList(b)
todoList.addToList(c)
while True:
todoList.executeReadyFunctions()
===
In pratica, si sarebbe probabilmente hanno più in corso in quel ciclo while non solo di verificare se le funzioni di timeout sono pronti ad andare. È possibile eseguire il polling per l'input dell'utente, controllare alcuni componenti hardware, leggere dati, ecc.
Questo non è ciò che 'setTimeout' fa in JavaScript. Quello che fa è mettere in coda una funzione per l'esecuzione successiva (cioè una volta scaduto il timeout). –
Sì ... Hai ragione. Ma volevo solo dare l'idea di quello che volevo, non ho trovato il bisogno di essere completamente tecnicamente corretto. – brunoais
La cosa migliore che potresti fare è prendere in giro qualcosa con i fili. –