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
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七月的小尾巴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值