详解python中自定义超时异常的几种方法
Python  /  管理员 发布于 7年前   168
最近在项目中调用第三方接口时候,经常会出现请求超时的情况,或者参数的问题导致调用异代码异常。针对超时异常,查询了python 相关文档,没有并发现完善的包来根据用户自定义的时间来抛出超时异常的模块。所以自己干脆自己来实现一个自定义的超时异常。目前找到了两种方式来实现超时异常的功能(signal.alarm()、threading实现超时异常)
方法1 thread + time
原理:将要调用的功能函数放入子线程,通过设定子线程的阻塞时间,超时则主线程并不会等待子线程的执行。主线程退出,子线程就不存在了。
核心就是在程序中添加 join()方法,用于等待线程结束。join()的作用是,在子线程完成运行之前,这个子线程的父线程将会被一直阻塞.
# coding=utf-8import threadingimport timedef myFunc(): time.sleep(4) print("myFunc执行了")if __name__ == '__main__': t = threading.Thread(target=myFunc) t.setDaemon(True) t.start() t.join(2) print("it's over")
执行结果:
it's over
可以看出,当主线程执行到2秒时候,结束退出。子线程还没有结束,没有执行完及被强制退出
# coding=utf-8import threadingimport timedef myFunc(): time.sleep(1) print("myFunc执行了")if __name__ == '__main__': t = threading.Thread(target=myFunc) t.setDaemon(True) t.start() t.join(2) print("it's over")
显示结果:
myFunc执行了
it's over
可以看出,子线程结束时,用时1秒,没有超过主线程设定的3秒,所以主线程与子线程都被执行了
方法 2 signal.alarm() ,注意两点:一是signal信号机制要在linux上才能运行; 二是signal信号在主线程中才会会起作用
import signalimport time# Define signal handler functiondef myHandler(signum, frame): exit("TimeoutError")def test_fun(): # time.sleep(3) int("afsdf") a = 2 + 3 return aif __name__ == '__main__': try: signal.signal(signal.SIGALRM, myHandler) signal.alarm(2) test = test_fun() print(test) signal.alarm(0) except Exception as ret: print("msg:", ret)
执行结果:
当 time.sleep(3) 时,会抛出TimeoutError的异常
当 test_fun 里面出现 int("afsdf")时, 会抛出 ValueError("invalid literal for int() with base 10: 'afsdf'",))
当test_fun函数执行的时间小于2 秒时,就会返回函数对应的值
方法3 带有返回值的超时异常,可以通过创建thread类的方式来进行捕捉
import threadingimport sysimport timeclass Dispacher(threading.Thread): def __init__(self, fun, args): threading.Thread.__init__(self) self.setDaemon(True) self.result = None self.error = None self.fun = fun self.args = args self.start() def run(self): try: self.result = self.fun(self.args) except: self.error = sys.exc_info()def test_fun(i): # time.sleep(4) a = i*i # b return adef main_fun(): c = Dispacher(test_fun, 2) c.join(2) if c.isAlive(): return "TimeOutError" elif c.error: return c.error[1] t = c.result return tif __name__ == '__main__': fun = main_fun() print(fun)
显示结果:
test_fun 执行时间大于设置的2秒时,会抛出TimeOutError
test_fun 执行时间小于设置的2秒时,并且函数正常执行时,显示:4
test_fun 里面出现比如 “b” 时,会抛出 global name 'b' is not defined 的异常
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号