Python捕获异常装饰器

0、装饰器的作用

  • 就代码层面而言,装饰器就是一个函数,这个函数可以接收一个函数作为参数。概况来说,就是形参是函数的函数。

  • 就使用场景而言,装饰器在原本函数实现的功能上,新实现了一些其他的功能。

  • 举个例子

    # encoding=utf-8
    
    
    def decorator(fun):
        def warp(*args, **kwargs):
            ret = fun(*args, **kwargs)
            print(f"计算结果是:{ret}")  # 新功能,打印计算的结果
            return ret
    
        return warp
    
    
    @decorator  # 使用装饰器 等价于 decorator(add)(3, 4)
    def add(a, b):
        """
        原生函数,实现加法功能
        :param a:
        :param b:
        :return:
        """
        return a + b
    
    
    if __name__ == '__main__':
        add(3, 4)
    

具体原理可参考 https://foofish.net/python-decorator.html

以下记录一下实现捕获异常的装饰器,不然每个函数都写try except太麻烦了

1、装饰器本身不带参数的装饰器

仅实现了try catch的功能

# encoding=utf-8


def catch_exception(func):
    """
    不带参数的装饰器
    :param func:
    :return:
    """

    def warp(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            print(f"执行[{func.__name__}]失败, args:{args}, kwargs:{kwargs} 异常:{e}")

    return warp


@catch_exception
def test_fun(*args, **kwargs):
    print(f"args是:{args}")
    print(f"kwargs是:{kwargs}")
    # 5/0
    return "--"


if __name__ == '__main__':
    print(test_fun(1, 2, a=1, b=2))

运行

  • 如果没有异常

    image-20220311200901182

  • 有异常被捕获(假设除数是0)

    image-20220311201017437

2、装饰器本身带参数的装饰器

想在1的基础上,可以实现函数名描述的传递以及有异常后的返回值自定义

# encoding=utf-8
from functools import wraps


def catch_exception(func_name=None, return_default=None):
    """
    带参数的装饰器
    :param func_name:
    :param return_default:
    :return:
    """

    def decorate(func):
        @wraps(func)
        def wrap(*args, **kwargs):
            if func_name:
                name = func_name
            else:
                name = func.__name__
            try:
                return func(*args, **kwargs)
            except Exception as e:
                print(f"执行[{name}]失败, args:{args}, kwargs:{kwargs} 异常:{e}")
                return return_default

        return wrap

    return decorate


@catch_exception(func_name="我是函数", return_default="==")
def test_fun(*args, **kwargs):
    print(f"args是:{args}")
    print(f"kwargs是:{kwargs}")
    # 5/0
    return "--"


if __name__ == '__main__':
    print(test_fun(1, 2, a=1, b=2))

运行

  • 如果没有异常

    image-20220311201111054

  • 有异常被捕获(假设除数是0)

image-20220311201138299

posted @ 2022-03-11 20:14  南风丶轻语  阅读(811)  评论(0编辑  收藏  举报