详解python中自定义超时异常的几种方法


Posted in Python onJuly 29, 2019

最近在项目中调用第三方接口时候,经常会出现请求超时的情况,或者参数的问题导致调用异代码异常。针对超时异常,查询了python 相关文档,没有并发现完善的包来根据用户自定义的时间来抛出超时异常的模块。所以自己干脆自己来实现一个自定义的超时异常。目前找到了两种方式来实现超时异常的功能(signal.alarm()、threading实现超时异常)

方法1 thread + time 

原理:将要调用的功能函数放入子线程,通过设定子线程的阻塞时间,超时则主线程并不会等待子线程的执行。主线程退出,子线程就不存在了。

核心就是在程序中添加 join()方法,用于等待线程结束。join()的作用是,在子线程完成运行之前,这个子线程的父线程将会被一直阻塞.

# coding=utf-8
import threading
import time


def 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-8
import threading
import time


def 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 signal
import time

# Define signal handler function
def myHandler(signum, frame):
  exit("TimeoutError")

def test_fun():
  # time.sleep(3)
  int("afsdf")
  a = 2 + 3
  return a

if __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 threading
import sys
import time


class 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 a
def 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 t

if __name__ == '__main__':
  fun = main_fun()
  print(fun)

显示结果:

test_fun 执行时间大于设置的2秒时,会抛出TimeOutError
test_fun 执行时间小于设置的2秒时,并且函数正常执行时,显示:4
test_fun 里面出现比如 “b” 时,会抛出 global name 'b' is not defined 的异常

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
用实例解释Python中的继承和多态的概念
Apr 27 Python
Django中URLconf和include()的协同工作方法
Jul 20 Python
深入剖析Python的爬虫框架Scrapy的结构与运作流程
Jan 20 Python
在centos7中分布式部署pyspider
May 03 Python
Python编程实现的简单Web服务器示例
Jun 22 Python
Python管理Windows服务小脚本
Mar 12 Python
对pandas中Series的map函数详解
Jul 25 Python
对python中词典的values值的修改或新增KEY详解
Jan 20 Python
python脚本当作Linux中的服务启动实现方法
Jun 28 Python
Python 中如何写注释
Aug 28 Python
Python 开发工具通过 agent 代理使用的方法
Sep 27 Python
基于Python中Remove函数的用法讨论
Dec 11 Python
Python 离线工作环境搭建的方法步骤
Jul 29 #Python
如何通过python的fabric包完成代码上传部署
Jul 29 #Python
Python八皇后问题解答过程详解
Jul 29 #Python
python 标准差计算的实现(std)
Jul 29 #Python
Python 二叉树的层序建立与三种遍历实现详解
Jul 29 #Python
Python完成哈夫曼树编码过程及原理详解
Jul 29 #Python
Python秒算24点实现及原理详解
Jul 29 #Python
You might like
PHP面向对象的进阶学习(抽像类、接口、final、类常量)
2012/05/07 PHP
php开发中的页面跳转方法总结
2015/04/26 PHP
php关联数组与索引数组及其显示方法
2018/03/12 PHP
laravel框架语言包拓展实现方法分析
2019/11/22 PHP
Javascript中的常见排序算法
2007/03/27 Javascript
javascript 全角转换实现代码
2009/07/17 Javascript
Javascript 函数中的参数使用分析
2010/03/27 Javascript
Javascript中拼接大量字符串的方法
2015/02/05 Javascript
JS动态修改图片的URL(src)的方法
2015/04/01 Javascript
PHP和NodeJs开发的应用如何共用Session
2015/04/16 NodeJs
js实现文本框宽度自适应文本宽度的方法
2015/08/13 Javascript
全屏js头像上传插件源码高清版
2016/03/29 Javascript
浅析Bootstrip的select控件绑定数据的问题
2016/05/10 Javascript
BootStrap Validator使用注意事项(必看篇)
2016/09/28 Javascript
简单的jQuery拖拽排序效果的实现(增强动态)
2017/02/09 Javascript
微信小程序 Nginx环境配置详细介绍
2017/02/14 Javascript
ajax +NodeJS 实现图片上传实例
2017/06/06 NodeJs
在vscode里使用.vue代码模板的方法
2018/04/28 Javascript
vue滚动tab跟随切换效果
2020/06/29 Javascript
关于vue路由缓存清除在main.js中的设置
2019/11/06 Javascript
Javascript表单序列化原理及实现代码详解
2020/10/30 Javascript
python中嵌套函数的实操步骤
2019/02/27 Python
python Gunicorn服务器使用方法详解
2019/07/22 Python
对YOLOv3模型调用时候的python接口详解
2019/08/26 Python
使用python去除图片白色像素的实例
2019/12/12 Python
pycharm工具连接mysql数据库失败问题
2020/04/01 Python
伦敦一卡通:The London Pass
2018/11/30 全球购物
Etam俄罗斯:法国女士内衣和家居服网上商店
2019/10/30 全球购物
上海中网科技笔试题
2012/02/19 面试题
在职人员函授期间自我评价分享
2013/11/08 职场文书
中学生打架检讨书
2014/10/13 职场文书
党校党性分析材料
2014/12/19 职场文书
教师节领导致辞
2015/07/29 职场文书
运动会100米广播稿
2015/08/19 职场文书
离婚协议书格式范本
2016/03/18 职场文书
Python 操作pdf pdfplumber读取PDF写入Exce
2022/08/14 Python