python 程序运行异常与计算耗时@装饰器

python程序运行异常与计算耗时使用@装饰器快捷方式

需求场景

在小才写python程序时,有时候需要保证程序在运行中不会因为某个方法的调用内部失败而导致整个程序的异常退出,于是我经常使用:

try:
    ...
except Exception as e:
    print("报错原因:", e)

来捕捉异常,但是这样做有几点不太方便

  1. 代码冗余。一个项目的方法加上类的成员方法不知道有多少了,这样每个地方都加上try…except…无疑显得很臃肿。
  2. 输出报错信息不好定位。报错信息需要每个方法都定义日志头。

装饰器代码

直接上小才使用的代码(嘲笑请偷偷)

'''
报错装饰器
'''
import inspect
import time
import traceback

def check_except(error_return=None, return_error=False, show_error=True, time_log=False):
    '''
    :param error_return:出错时的返回值
    :param return_error: 是否返回错误信息
    :param show_error: 是否输出错误信息
    :return:
    '''

    def wrapper(func):
        def inner(*args, **kwargs):
            rules = func.__annotations__  # 获取参数与返回值的注解
            args_num = len(inspect.getfullargspec(func).args)
            for name, value in kwargs.items():  # 检查传入的关键字参数类型
                if name in rules:
                    if not isinstance(value, rules[name]):
                        raise RuntimeError('%s want %s, but %s' % (name, rules[name], type(value)))
            try:
                if time_log:
                    t1 = time.perf_counter()
                    back = func(*args[:args_num], **kwargs)
                    t2 = time.perf_counter()
                    print("[INFO] ", func.__qualname__, " 耗时:", t2 - t1)
                else:
                    back = func(*args[:args_num], **kwargs)
                if 'return' in rules and not isinstance(back, rules['return']):  # 检查返回值类型
                    raise RuntimeError('return want %s, but %s' % (rules['return'], type(back)))
                # 如果设置返回错误信息
                if return_error:
                    # code 1表示未出错
                    return {"code": 1, "return": back}
                else:
                    return back
            except Exception as e:
                # 如果输出错误
                if show_error:
                    traceback.print_exc()
                    print("[ERROE] ", func.__qualname__, " 出错,原因:", e)
                # 如果设置返回错误信息
                if return_error:
                    # 报错返回预设置值
                    # code 0表示未出错
                    return {"code": 0, "return": error_return, "info": e}
                else:
                    return return_error
        return inner
    return wrapper

小才还加上了计时的功能,一些参数可以看情况使用,只需要进行异常捕获的话,一般小才我都是直接在方法上打上@check_except()就够用了。

使用案例

if __name__ == '__main__':
    @check_except()
    def test():
        print(1 / 0)
    test()
    print("小才测试异常捕获")

输出:

Traceback (most recent call last):
File “E:\learning\writing-articles\my-success\pyqt5可编辑标签页\check_except.py”, line 32, in inner
back = func(*args[:args_num], **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “E:\learning\writing-articles\my-success\pyqt5可编辑标签页\check_except.py”, line 60, in test
print(1 / 0)
^
ZeroDivisionError: division by zero
[ERROE] test 出错,原因: division by zero
小才测试异常捕获

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是个人才呐

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

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

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

打赏作者

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

抵扣说明:

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

余额充值