Ответ 1
На практике Timer, вероятно, самый простой способ сделать то, что вы хотите.
Этот код будет выполнять следующие действия:
- Через 1 секунду он печатает "arg1 arg2"
- Через 2 секунды он печатает "OWLS OWLS OWLS"
===
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()
===
Вышеупомянутый код, скорее всего, решит вашу проблему.
Но! Существует альтернативный способ, который не использует многопоточность. Он работает намного больше, чем Javascript, который является однопоточным.
Для этой однопоточной версии все, что вам нужно сделать, это сохранить функцию и ее аргументы в объекте вместе с временем, в которое должна выполняться функция.
Как только у вас есть объект, содержащий вызов функции и тайм-аут, просто периодически проверяйте, готова ли функция к выполнению.
Правильный способ сделать это - сделать приоритетную очередь для хранения всех функций, которые мы хотим запустить в будущем, как показано в приведенном ниже коде.
Как и в Javascript, этот подход не гарантирует, что функция будет работать точно вовремя. Функция, которая занимает очень много времени, будет задерживать функции после нее. Но это гарантирует, что функция будет выполняться не раньше, чем ее таймаут.
Этот код будет выполнять следующие действия:
- Через 1 секунду он печатает "20"
- Через 2 секунды он печатает "132"
- Через 3 секунды он завершает работу.
===
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 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()
===
На практике у вас, вероятно, будет больше возможностей в этом цикле, чем просто проверка того, готовы ли ваши функции тайм-аута. Вы можете проводить опрос для ввода пользователем, управлять некоторым оборудованием, считывать данные и т.д.