Python中异常重试的解决方案详解


Posted in Python onMay 05, 2017

前言

大家在做数据抓取的时候,经常遇到由于网络问题导致的程序保存,先前只是记录了错误内容,并对错误内容进行后期处理。

原先的流程:

def crawl_page(url):
 pass
 
def log_error(url):
 pass
 
url = ""
try:
 crawl_page(url)
except:
 log_error(url)

改进后的流程:

attempts = 0
success = False
while attempts < 3 and not success:
 try:
  crawl_page(url)
  success = True
 except:
  attempts += 1
  if attempts == 3:
   break

最近发现的新的解决方案:retrying

retrying是一个 Python的重试包,可以用来自动重试一些可能运行失败的程序段。retrying提供一个装饰器函数retry,被装饰的函数就会在运行失败的条件下重新执行,默认只要一直报错就会不断重试。

import random
from retrying import retry
 
@retry
def do_something_unreliable():
 if random.randint(0, 10) > 1:
  raise IOError("Broken sauce, everything is hosed!!!111one")
 else:
  return "Awesome sauce!"
 
print do_something_unreliable()

如果我们运行have_a_try函数,那么直到random.randint返回5,它才会执行结束,否则会一直重新执行。

retry还可以接受一些参数,这个从源码中Retrying类的初始化函数可以看到可选的参数:

  • stop_max_attempt_number:用来设定最大的尝试次数,超过该次数就停止重试
  •  stop_max_delay:比如设置成10000,那么从被装饰的函数开始执行的时间点开始,到函数成功运行结束或者失败报错中止的时间点,只要这段时间超过10秒,函数就不会再执行了
  • wait_fixed:设置在两次retrying之间的停留时间
  • wait_random_min和wait_random_max:用随机的方式产生两次retrying之间的停留时间
  • wait_exponential_multiplier和wait_exponential_max:以指数的形式产生两次retrying之间的停留时间,产生的值为2^previous_attempt_number * wait_exponential_multiplierprevious_attempt_number是前面已经retry的次数,如果产生的这个值超过了wait_exponential_max的大小,那么之后两个retrying之间的停留值都为wait_exponential_max。这个设计迎合了exponential backoff算法,可以减轻阻塞的情况。
  • 我们可以指定要在出现哪些异常的时候再去retry,这个要用retry_on_exception传入一个函数对象:
def retry_if_io_error(exception):
 return isinstance(exception, IOError)
 
@retry(retry_on_exception=retry_if_io_error)
def read_a_file():
 with open("file", "r") as f:
  return f.read()

在执行read_a_file函数的过程中,如果报出异常,那么这个异常会以形参exception传入retry_if_io_error函数中,如果exceptionIOError那么就进行retry,如果不是就停止运行并抛出异常。

我们还可以指定要在得到哪些结果的时候去retry,这个要用retry_on_result传入一个函数对象:

def retry_if_result_none(result):
 return result is None
 
@retry(retry_on_result=retry_if_result_none)
def get_result():
 return None

在执行get_result成功后,会将函数的返回值通过形参result的形式传入retry_if_result_none函数中,如果返回值是None那么就进行retry,否则就结束并返回函数值。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python中将字典转换为列表的方法
Sep 21 Python
python使用KNN算法手写体识别
Feb 01 Python
在cmder下安装ipython以及环境的搭建
Oct 19 Python
pycharm的console输入实现换行的方法
Jan 16 Python
Python在OpenCV里实现极坐标变换功能
Sep 02 Python
浅谈tensorflow之内存暴涨问题
Feb 05 Python
Python logging模块写入中文出现乱码
May 21 Python
浅谈Keras参数 input_shape、input_dim和input_length用法
Jun 29 Python
Python reversed反转序列并生成可迭代对象
Oct 22 Python
python 实现逻辑回归
Dec 30 Python
PyQt5中QSpinBox计数器的实现
Jan 18 Python
python绘制简单直方图(质量分布图)的方法
Apr 21 Python
Django的信号机制详解
May 05 #Python
Python中模块与包有相同名字的处理方法
May 05 #Python
详解python 字符串和日期之间转换 StringAndDate
May 04 #Python
Pycharm学习教程(7)虚拟机VM的配置教程
May 04 #Python
python 统计代码行数简单实例
May 04 #Python
利用PyInstaller将python程序.py转为.exe的方法详解
May 03 #Python
Pycharm学习教程(6) Pycharm作为Vim编辑器使用
May 03 #Python
You might like
php rmdir使用递归函数删除非空目录实例详解
2016/10/20 PHP
laravel自定义分页效果
2017/07/23 PHP
Laravel 批量更新多条数据的示例
2017/11/27 PHP
PHP双向链表定义与用法示例
2018/01/31 PHP
根据对象的某一属性进行排序的js代码(如:name,age)
2010/08/10 Javascript
实现变速回到顶部的JavaScript代码
2011/05/09 Javascript
THREE.JS入门教程(2)着色器-上
2013/01/24 Javascript
js数组Array sort方法使用深入分析
2013/02/21 Javascript
基于 Docker 开发 NodeJS 应用
2014/07/30 NodeJs
JavaScript的Vue.js库入门学习教程
2016/05/23 Javascript
jQuery Form表单取值的方法
2017/01/11 Javascript
vue路由嵌套的SPA实现步骤
2017/11/06 Javascript
红黑树的插入详解及Javascript实现方法示例
2018/03/26 Javascript
JS实现获取进今年第几天是周几的方法分析
2018/06/27 Javascript
微信小程序 确认框的实现(附代码)
2019/07/23 Javascript
vue中input的v-model清空操作
2019/09/06 Javascript
解决antd 下拉框 input [defaultValue] 的值的问题
2020/10/31 Javascript
python 随机数生成的代码的详细分析
2011/05/15 Python
python通过正则查找微博@(at)用户的方法
2015/03/13 Python
Python自动重试HTTP连接装饰器
2015/04/28 Python
Python使用lxml模块和Requests模块抓取HTML页面的教程
2016/05/16 Python
Python中文件I/O高效操作处理的技巧分享
2017/02/04 Python
python学习之matplotlib绘制散点图实例
2017/12/09 Python
python编写微信远程控制电脑的程序
2018/01/05 Python
python实现列表中由数值查到索引的方法
2018/06/27 Python
python实现本地图片转存并重命名的示例代码
2018/10/27 Python
Python基于datetime或time模块分别获取当前时间戳的方法实例
2019/02/19 Python
pandas将多个dataframe以多个sheet的形式保存到一个excel文件中
2019/10/10 Python
python下载卫星云图合成gif的方法示例
2020/02/18 Python
使用Canvas操作像素的方法
2018/06/14 HTML / CSS
保健品市场营销方案
2014/03/31 职场文书
2016公司新年问候语
2015/11/11 职场文书
高一数学教学反思
2016/02/18 职场文书
vue backtop组件的实现完整代码
2021/04/07 Vue.js
MySQL分区路径子分区再分区
2022/04/13 MySQL
JS前端轻量fabric.js系列物体基类
2022/08/05 Javascript