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中列表生成式和生成器的区别
Aug 03 Python
windows下安装Python的XlsxWriter模块方法
May 03 Python
对python过滤器和lambda函数的用法详解
Jan 21 Python
Python语言检测模块langid和langdetect的使用实例
Feb 19 Python
python实现字符串加密 生成唯一固定长度字符串
Mar 22 Python
基于Python+Appium实现京东双十一自动领金币功能
Oct 31 Python
python分布式计算dispy的使用详解
Dec 22 Python
Python Pickle 实现在同一个文件中序列化多个对象
Dec 30 Python
Python如何自动获取目标网站最新通知
Jun 18 Python
Python 实现国产SM3加密算法的示例代码
Sep 21 Python
Python如何利用Har文件进行遍历指定字典替换提交的数据详解
Nov 05 Python
用Python 执行cmd命令
Dec 18 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中for循环语句的几种变型
2006/11/26 PHP
一步一步学习PHP(1) php开发环境配置
2010/02/15 PHP
PHP获取windows登录用户名的方法
2014/06/24 PHP
php去掉URL网址中带有PHPSESSID的配置方法
2014/07/08 PHP
PHP中使用php://input处理相同name值的表单数据
2015/02/03 PHP
PHP后期静态绑定之self::限制实例分析
2018/12/21 PHP
javascript第一课
2007/02/27 Javascript
更换select下拉菜单背景样式的实现代码
2011/12/20 Javascript
JQUERY 获取IFrame中对象及获取其父窗口中对象示例
2013/08/19 Javascript
JavaScript四种调用模式和this示例介绍
2014/01/02 Javascript
JS实现将人民币金额转换为大写的示例代码
2014/02/13 Javascript
window.open()详解及浏览器兼容性问题示例探讨
2014/05/29 Javascript
简介JavaScript中的italics()方法的使用
2015/06/08 Javascript
JavaScript变量的作用域全解析
2015/08/14 Javascript
JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)
2016/12/14 Javascript
BootstrapValidator实现注册校验和登录错误提示效果
2017/03/10 Javascript
vue组件之Alert的实现代码
2017/10/17 Javascript
原生JS实现 MUI导航栏透明渐变效果
2017/11/07 Javascript
使用FileReader API创建Vue文件阅读器组件
2018/04/03 Javascript
微信小程序实现展示评分结果功能
2019/02/15 Javascript
简单了解JavaScript中的执行上下文和堆栈
2019/06/24 Javascript
vue el-table实现行内编辑功能
2019/12/11 Javascript
微信小程序 scroll-view的使用案例代码详解
2020/06/11 Javascript
Element Badge标记的使用方法
2020/07/27 Javascript
React实现轮播效果
2020/08/25 Javascript
JQuery绑定事件四种实现方法解析
2020/12/02 jQuery
详解Django+Uwsgi+Nginx 实现生产环境部署
2018/11/06 Python
Django处理多用户类型的方法介绍
2019/05/18 Python
Python实现 PS 图像调整中的亮度调整
2019/06/28 Python
Python 日期时间datetime 加一天,减一天,加减一小时一分钟,加减一年
2020/04/16 Python
基于python计算滚动方差(标准差)talib和pd.rolling函数差异详解
2020/06/08 Python
python爬取抖音视频的实例分析
2021/01/19 Python
仓库主管岗位职责
2014/03/02 职场文书
预备党员个人总结
2015/02/14 职场文书
python scipy 稀疏矩阵的使用说明
2021/05/26 Python
nginx配置指令之server_name的具体使用
2022/08/14 Servers