我想编写一个函数,无论如何都将在5秒后返回:
def myfunction():
while passed_time < 5_seconds:
do1()
do2()
do3()
.
.
return
我的意思是,这个函数只运行5秒,5秒后它应该结束,并继续其他功能:
myfunction()
otherfunction() ----> This should start 5 seconds after myfunction() is executed.
最好的问候
答案 0 :(得分:4)
你可以这样做:
def myfunction():
start = time.time()
while time.time() < start + 5:
do1()
do2()
do3()
请注意,这将在至少 5秒后停止 - 如果do1
,do2
和do3
各占3秒,则此功能将需要9秒。
如果您想在这些来电之间切断myFunction
,可以执行以下操作:
def myfunction():
todo = itertools.cycle([do1, do2, do3])
start = time.time()
while time.time() < start + 5:
todo.next()()
这种情况需要6s
答案 1 :(得分:3)
如果函数的执行时间可能比触发这些函数的时间间隔长,则必须在另一个线程或进程中启动这些函数。
threading
的示例:
import time
import sys
from threading import Thread
def f1():
print "yo!!"
time.sleep(6)
def f2():
print "boring."
time.sleep(2)
if __name__ == "__main__":
threads = []
try:
for f in [f1, f2]:
t = Thread(target=f)
t.start()
threads.append(t)
time.sleep(5)
except KeyboardInterrupt:
sys.exit(0)
finally:
[t.join() for t in threads]
我理解的问题是你不一定需要在5秒后杀死/结束一个函数。您的主要目标是以5秒的间隔启动功能。如果你需要在一段时间后“杀死”这些函数,那么使用线程并不是一件容易的事:Is there any way to kill a Thread in Python?
答案 2 :(得分:1)
你也可以这样做:
import time
start=time.time()
stuff={1:do1,2:do2,3:do3,...}
i=1
while time.time() <= start+5:
stuff[i]()
i+=1
答案 3 :(得分:1)
从您定义问题的方式来看,我认为使用基于生成器的协同例程是一个很好的情况。也就是说,将myFunction
更改为yield
每次完成其处理步骤(例如do1
或do2
)并从循环运行它的生成器检查时间。
这是一个重复运行单个somework
函数的简单实现,但您可以轻松调用不同的函数,甚至可以直接在myFunction
生成器中工作:
import time
def somework():
print "Doing some work!"
time.sleep(2)
def myFunction():
try:
print "Started myFunction()"
yield somework()
yield somework()
yield somework()
yield somework()
yield somework()
print "Done with myFunction()"
except GeneratorExit:
print "Exiting myFunction() early!"
def main():
start = time.time()
gen = myFunction()
for _ in gen:
if time.time() > start+5:
gen.close();
使用此结构有一些好处:
myFunction
可以选择yield
到外循环的位置,这样就不会在意外时间被杀死。如果它正在操纵某些外部数据结构,您可以确保它始终在一致状态下产生所有内容。myFunction
可以产生中间值,如果有用的话。上面的示例代码产生None
(因为这是来自somework
的返回值,但您可以轻松地更改它。主循环将最新的屈服值放在_
变量中(未使用) ),但是如果需要,可以重命名该变量并在超时块中使用其值。GeneratorExit
异常,myFunction
可以在关闭之前运行所需的任何清理代码。