python每日习题:自己封装失败重跑装饰器
Posted 七月的小尾巴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python每日习题:自己封装失败重跑装饰器相关的知识,希望对你有一定的参考价值。
题目
实现一个重运行的装饰器,可以用来装饰任何一个功能函数,只要被装饰的函数执行出现AssertionError,
则重新执行该函数,同一个函数最多重运行三次。
下面讲一下小余在做这道题的心里历程,从昨天下班的时候,看到这道题目做起来真的很上头,一直写到晚上一点钟。
当我第一次看到这倒题目的时候,想到的就是递归调用实现
def test_run(func):
def swapper(a, b, count=0):
try:
func(a, b)
except AssertionError:
if count < 3:
print("断言失败,开始尝试失败重跑,当前尝试第{}次重跑".format(count+1))
swapper(a, b, count+1)
return swapper
@test_run
def test(a, b):
assert a == b
写的时候很快,但是当我重新看题目的时候,突然发现题目中的关键字, 可以用来装饰任何一个功能函数
,突然发现,我直接用 a,b形参了。于是又重新整理了一下思路:
写的飞快,但是执行的时候,发现了这种思路并不可行,从debug中,我们可以看到,实参中10,直接作为count被传了,导致再if条件判断下并没有执行这行代码。
于是又换了一种思路,count的值,作为装饰器参数传递:
本来一开始想的是,装饰器传递参数,然后去更改装饰器的值,判断失败重跑,但是抛了一个语法错误。嵌套函数里面仿佛是无法更改外层的函数值内容。(这里有厉害的宝子,可以一起沟通哦~已经涉及到小余的知识盲区了)
最后改来改去,改成了下面的方法实现:
def test_assert(func):
def swapper(*args, **kwargs):
# 执行函数,判断如果函数执行失败,return "AssertionError"
def start_func(*args, **kwargs):
try:
func(*args, **kwargs)
except AssertionError:
return "AssertionError"
count = 0
# 调用函数
res = start_func(*args, **kwargs)
# 判断当函数出现异常并且异常次数小于 3 次
if res == "AssertionError":
if count <= 3:
for i in range(3):
print("断言失败,开始尝试失败重跑,当前尝试第{}次重跑".format(i))
# 失败重跑
a = start_func(*args, **kwargs)
count += 1
# 当用例执行通过,则直接退出
if a != "AssertionError":
break
else:
pass
return swapper
但是写完之后,我总觉得功能虽然实现了,但是整体的写法上面,并不是我想要的效果,那么我们来看看终极版:
def decorator(func):
def wrapper(*args, **kwargs):
for i in range(4):
try:
res = func(*args, **kwargs)
except AssertionError as e:
# 判断当用例执行到第三次的时候,抛异常
if i == 3:
raise e
else:
# 执行通过,直接返回函数内容
return res
return wrapper
@decorator
def test(a, b):
print("这里是函数内容")
assert a == b
以上是关于python每日习题:自己封装失败重跑装饰器的主要内容,如果未能解决你的问题,请参考以下文章
解决报错:在Python中使用property装饰器时,出现错误:TypeError: descriptor ‘setter‘ requires a ‘property‘ object but(代码片