Python, 在X秒后尝试、异常语句超时?
我一直在找这个问题的答案,但总是找到一些比较复杂的内容,比如多线程之类的。我其实只是想做一个像“尝试,捕获”那样的语句,如果某个过程在X秒内没有完成,就抛出一个异常。
补充说明:我之所以这样做,是因为我在使用一个网站测试软件(selenium),它的配置有时候会导致程序卡住。这个时候它不会报错,也不会超时,也没有任何反应,所以我没有办法捕捉到这个问题。我想知道有什么好的方法来判断这种情况发生了,这样我就可以继续我的应用程序。我在想,如果我能做类似“如果在X秒内没有完成……就继续”的事情就好了。
3 个回答
如果你在使用UNIX系统,这里有一个通用的解决方案:
import time as time
import signal
#Close session
def handler(signum, frame):
print 1
raise Exception('Action took too much time')
signal.signal(signal.SIGALRM, handler)
signal.alarm(3) #Set the parameter to the amount of seconds you want to wait
try:
#RUN CODE HERE
for i in range(0,5):
time.sleep(1)
except:
print 2
signal.alarm(10) #Resets the alarm to 10 new seconds
signal.alarm(0) #Disables the alarm
你不能不使用某种多线程或多进程的方式来实现这个,即使这些技术在某些抽象层下被隐藏起来,除非你运行的“进程”是专门为异步设计的,并且会定期调用一个已知的函数。
如果你能描述一下这个进程到底是什么,那就更容易提供实际的解决方案了。我觉得你可能还没有意识到Python在实现简洁而完整的功能方面的强大。即使使用多线程或多进程,可能只需要几行代码就能实现。
这个回答(还有问题)并不是专门针对try/except语句的。如果你想要一个无限循环,但又希望它能在一段时间后停止,那它可能就不应该是无限的。比如,可以把它改成这样:
while time <= some_value:
或者在循环的主体中添加一个额外的检查,让它在你想停止的时候跳出循环:
while True:
...
if time > some_value:
break
如果这样做不可能(比如你完全控制不了这个循环),那事情就会变得相当复杂。在很多系统中,你可以使用signal.alarm
来设置一个定时器,过一段时间后发送一个信号,然后用一个信号处理器来处理signal.SIGALRM
,这样就可以抛出你的TimeoutError
异常。不过,这种方法是否有效取决于这个无限循环的具体情况;如果它阻塞了信号,或者捕获并忽略了异常,或者以其他方式干扰了信号处理器,那就不行了。另一种可能性是把循环放在一个单独的进程中,这样你就可以随时终止这个进程。不过,除了终止它之外,做其他事情会很困难,所以清理或恢复部分工作也会非常麻烦。(线程是行不通的,因为没有办法中断正在执行无限循环的线程。)