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 cookielib 登录人人网的实现代码
Dec 19 Python
Python while 循环使用的简单实例
Jun 08 Python
Python判断某个用户对某个文件的权限
Oct 13 Python
python2.7和NLTK安装详细教程
Sep 19 Python
python assert的用处示例详解
Apr 01 Python
利用Python+阿里云实现DDNS动态域名解析的方法
Apr 01 Python
基于python二叉树的构造和打印例子
Aug 09 Python
python使用openpyxl操作excel的方法步骤
May 28 Python
python图片合成的示例
Nov 09 Python
分享unittest单元测试框架中几种常用的用例加载方法
Dec 02 Python
Pycharm 跳转回之前所在页面的操作
Feb 05 Python
Python日志模块logging用法
Jun 05 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
Ubuntu VPS中wordpress网站打开时提示”建立数据库连接错误”的解决办法
2016/11/03 PHP
Discuz不使用插件实现简单的打赏功能
2019/03/21 PHP
TP5框架实现的数据库备份功能示例
2020/04/05 PHP
HTML IMG标签 onload 内存溢出导致浏览器CPU占用过高
2021/03/09 Javascript
Jquery下的26个实用小技巧(jQuery tips, tricks &amp; solutions)
2010/03/01 Javascript
关于onScroll事件在IE6下每次滚动触发三次bug说明
2011/09/21 Javascript
FireFox下XML对象转化成字符串的解决方法
2011/12/09 Javascript
JQueryEasyUI Layout布局框架的使用
2013/04/08 Javascript
jquery用offset()方法获得元素的xy坐标
2014/09/06 Javascript
js精美的幻灯片画集特效代码分享
2015/08/29 Javascript
JavaScript递归操作实例浅析
2016/10/31 Javascript
JS绘制微信小程序画布时钟
2016/12/24 Javascript
JS打开摄像头并截图上传示例
2017/02/18 Javascript
微信分享调用jssdk实例
2017/06/08 Javascript
自定义PC微信扫码登录样式写法
2017/12/12 Javascript
Es6 Generator函数详细解析
2018/02/24 Javascript
webpack4+express+mongodb+vue实现增删改查的示例
2018/11/08 Javascript
关于JSON解析的实现过程解析
2019/10/08 Javascript
Python中使用装饰器和元编程实现结构体类实例
2015/01/28 Python
python实现教务管理系统
2018/03/12 Python
对python的bytes类型数据split分割切片方法
2018/12/04 Python
python字符串循环左移
2019/03/08 Python
Python函数定义及传参方式详解(4种)
2019/03/18 Python
python如何爬取网站数据并进行数据可视化
2019/07/08 Python
解决Django Static内容不能加载显示的问题
2019/07/28 Python
Keras构建神经网络踩坑(解决model.predict预测值全为0.0的问题)
2020/07/07 Python
Python pymsql模块的使用
2020/09/07 Python
html5基础教程常用技巧整理
2013/08/20 HTML / CSS
中国综合网上购物商城:苏宁易购
2016/08/09 全球购物
银行类自荐信
2014/02/04 职场文书
股东协议书
2014/04/14 职场文书
数学教育专业求职信
2014/07/22 职场文书
运动会广播稿200字(10篇)
2014/10/12 职场文书
云冈石窟导游词
2015/02/04 职场文书
欠条格式范本
2015/07/03 职场文书
使用Ajax实现进度条的绘制
2022/04/07 Javascript