没人想被这些事搞砸!重试装饰器助你一臂之力
云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!
“胶水语言”,顾名思义,意味着这种语言有助于将连接系统,确保数据能以所需结构和格式,由A转到B。Python就是知名度最高的一种胶水语言。笔者曾用Python构建了无数的ETL脚本(数据提取、转换和加载)。
这些脚本基本上都按照相同规则运行。从某处提取数据,数据转化,然后运行最后一步——将数据上传到某个地方,但也可能是有条件的删除。
越来越多的传统公司的基础设施正在被上传到云端,越来越多的公司正在向微服务方式转型。这也意味着一种情况出现的可能大大增加:必须从某个地方提取数据,或从非本地计算机处写入数据。
小规模的操作很少出问题。如果某些提取或者回写失败,通常会被注意到,且错误能被纠正。
但如果操作规模更大,并存在成百上千的可能事项时,就会出现暂时中断的网络连接、过多的并发写入、暂时没有相应的源系统或者其他莫名其妙的问题,而没人想被这些事情搞砸。而笔者发现了一个非常简单的重试装饰器,它能解决这些问题。
笔者在大多数项目中都会在某个功能模块中使用重试装饰器,可谓是“大救星”。快来看看吧!
装饰器
函数是一级对象
在Python中,函数是一级对象。函数和其他任何对象一样。这一事实意味着函数可以动态创建、传递给函数本身,甚至可以更改。下面这个示例尽管很傻但确是事实:
def my_function(x): print(x)IN: my_function(2) OUT: 2IN: my_function.yolo = you live only once print(my_function.yolo) OUT: you live only once
修饰语法
为了方便开发人员,Python提供了一种特殊的语法。还可以按如下方式操作:
@convert_to_numeric def first_func(x): return x**2
以上的语法等同于:
def first_func(x): return x**2first_func =convert_to_numeric(first_func)
这种语法使实际运行情况更清楚,尤其是在使用多个装饰器的情况下。
修饰函数
可以用另一个函数包装一个函数来满足特定需求,这一点很有用。例如,可以确保函数在被调用时向某个日志端点报告,打印出参数,实现类型检查、预处理或后处理,以列出一些可能性。以下为一个简单示例:
def first_func(x): return x**2 def second_func(x): return x - 2
当用字符串 2 调用这两个函数时,其都会无法工作。可在其中使用一个类型转换函数,并且用其修饰first_func 和 second_func 。
def convert_to_numeric(func): # define a function within the outerfunction def new_func(x): return func(float(x)) # return the newly defined function return new_func
这个convert_to_numeric 包装函数需要用一个函数作为参数,并返回另一个函数。现在,虽然先前无法工作,但是如果包装了函数,然后用一个字符串号调用,所有的函数都能按设置的使用。
IN: new_fist_func = convert_to_numeric(first_func)############################### convert_to_numeric returns this function: def new_func(x): return first_func(float(x)) ###############################new_fist_func( 2 ) OUT: 4.0IN: convert_to_numeric(second_func)( 2 ) OUT: 0
这是为什么?
convert_to_numeric接受一个函数(A)作为参数并返回一个新函数(B)。新函数(B)在被调用时调用函数(A),但它不是用传递的参数x调用函数(A),而是用float(x)调用函数(A),从而解决了以前的TypeError 问题。
重试!
基本知识已经介绍完了,现在讲一讲笔者最喜欢的retry装饰器:
包装已经包装的函数。是一些初始阶段的内容,这并不复杂!
来一步一步了解代码:
1.最外层函数retry:这将参数化修饰器,即要处理的异常是什么,尝试的频率是多少,两次尝试之间等待的时间是多长,以及指数退避因子是什么(即每次失败时,用什么数字乘以等待时间)。
2.retry_decorator:这是参数化的装饰器,由retry函数返回。用@wraps来修饰retry_decorator中的函数。严格来讲,这在功能上是不必要的。这个包装器更新了包装函数的 name 和 doc (如果不这样做,函数的 name 始终是 func_with_retries)。
3.func_with_retries应用重试逻辑。此函数包装了try-except语句块中的函数调用,并实现指数退避等待和一些日志记录。
用途:
函数用重试装饰器修饰,在异常上最多重试四次。或者更具体一点:
用在TimeoutError上的重试装饰的函数最多重试两次。
结果:
调用修饰函数,并遇到错误,将会导致如下结果:
调用的函数在ConnectionRefusedError上失败两次,在ConnectionResetError上失败一次,在第四次尝试时成功。这里有良好的日志记录,打印了args和kwargs以及函数名,使调试和修复问题变得轻而易举(如果重试次数用完错误依然存在)。
了解装饰器如何在Python中工作,以及如何用一个简单的重试装饰器来修饰关键任务函数,这非常有必要的。它是面对不确定情况时的“大救星”!
【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/zhibo立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
作为后端开发如何设计数据库系列文章(一)设计传统系统表结构(Java开发)
本篇为第一篇。讲解传统系统的表结构设计(Java开发)。 讲讲如何避免数据库设计的一些坑,方便后期的开发与维护。 以前经常能够看到,数据库范式,现在说数据库三大范式的少了。 三大范式我以前也很严格的弄过,但是后来发现,还是灵活好啊,为什么,业务变动太快了啊,按照范式来,结构变更顶不住。 下面我就说一说设计数据库表要注意的一些地方吧。我不是DBA,只是Java后端开发,以下是根据我的个人经验所得,至于能不能体会,看个人了。 外键、触发器 外键、触发器不要有。有了外键、触发器,你会发现: 写代码不方便。 订正数据不方便。 迁移数据也麻烦。 总之,你要是坚持用,后续的坑等着你。 自增id 数据库表,一定要有id,而且要用自增id!有些人喜欢用自定义的,用UUID或者其他七七八八的id,如果在架构设计,代码比较好的情况下,不会出啥大问题,但是一旦代码写的
- 下一篇
Python办公自动化之从Word到Excel
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 大家好,今天有一个公务员的小伙伴委托我给他帮个忙,大概是有这样一份Word(由于涉及文件私密所以文中的具体内容已做修改) 一共有近2600条类似格式的表格细栏,每个栏目包括的信息有: 日期发文单位文号标题签收栏需要提取其中加粗的这三项内容到Excel表格中存储,表格样式如下: 也就是需要将收文时间、文件标题、文号填到指定位置,同时需要将时间修改为标准格式,如果是完全手动复制和修改时间,依照一个条目10s的时间计算,一分钟可以完成6条,那么最快也需要: 而这类格式规整的文件整理非常适合用Python来执行,好的那么接下来请Python出场,必要的信息我在代码中以注释信息呈现。 首先使用Python将Word文件导入 # 导入需要的库docx from docx import Document # 指定文件存放的路径 path = r'C:\Users\word.docx' # 读取文件 document = Document(path) # 读取word中的所有表格 tables = do...
相关文章
文章评论
共有0条评论来说两句吧...