• python decorator


    Python decorator 记录


    前言

    简单记录,不断更新。

    提示:以下是本篇文章正文内容,下面案例可供参考

    一、decorator简介

    decorator 本质是一个函数,与其他函数不同的是,它的的入参也是一个函数,返回值是一个对象,可以让其他函数在不增加代码的前提下增加额外功能。

    二、应用场景

    插入日志,计算运行时间,事物处理。
    有了decorator,可以抽离出大量与函数功能本身无关的雷同代码。

    三、分类

    函数decorator和类decorator

    四、基本使用

    1. 基础使用

    case1: 记录一个函数执行所需时间
    original code:

    def func1():
        startTime = time.time()
        print("this is func1")
        time.sleep(2)
        execTime = time.time()-startTime
        print("total exec time %s." % execTime)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果想要记录一百个函数的执行时间,会有大量雷同代码。因此,使用decorator
    now:

    
    def timeCalc(func):
        def wrapper():
            startTime = time.time()
            func()  # exec func
            execTime = time.time()-startTime
            print("%s exec need time %s" %(func.__name__, execTime))
        return wrapper
    
    # @timeCalc = timeCalc(fun3)
    @timeCalc
    def fun3():
        time.sleep(3)
    
    @timeCalc   
    def fun4():
        time.sleep(4)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2. 带参数的decorator

    def timeCalc(func):
        def wrapper(*args, **kwargs):
            startTime = time.time()
            func(*args, **kwargs)  # exec func
            execTime = time.time()-startTime
            print("%s exec need time %s" %(func.__name__, execTime))
        return wrapper
    
    @timeCalc
    def funcAdd(x, y):
        print('x + y = ', x+y)
        time.sleep(1)
    
    @timeCalc
    def funcAddMore(x, y, z):
        print('x + y + z = ', x+y+z)
        time.sleep(2)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3. decorator本身可以带para

    def timeCalc(level):
        def outWrapper(func):
            def wrapper(*args, **kwargs):
                startTime = time.time()
                func(*args, **kwargs)  # exec func
                execTime = time.time()-startTime
                print("%s %s exec need time %s" %(level, func.__name__, execTime))
            return wrapper
        return outWrapper
    
    @timeCalc(level="info")
    def funcAdd2(x, y):
        print('x + y = ', x+y)
        time.sleep(1)
    
    @timeCalc(level="debug")
    def funcAddMore2(x, y, z):
        print('x + y + z = ', x+y+z)
        time.sleep(2)
    
    funcAdd2(1,2)
    funcAddMore2(1,2,3)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    4. 实际使用

    background: try-catch 的使用降低代码的可读性,使用decorator 减少try-catch. 当func抛出异常时,decorator默认catch exception.

    DEFAULT_FAULT_KEY = "defaultKey"
    
    def RunTaskFunc(taskFunc, fault, funName):
        logger.error("output all kinds of info %s %s" % (fault, funName))
        try:
            taskFunc()
        except Exception as e:
            logger.exception("exception")
    
    def taskGuard(fault=DEFAULT_FAULT_KEY):
        def inner(func):
            @functools.wraps(func)
            def wrapper(task, **kwargs):
                RunTaskFunc(lambda: func(task, **kwargs),
                            fault, func.__name__)
            return wrapper
        return inner
        
    @taskGuard(fault="commonFuncKey")
    def commonFunc(task="task"):
        a = 1/0
        return
    
    commonFunc(task="commonFuncTask")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    [附源码]JAVA毕业设计砂石矿山管理系统(系统+LW)
    在{{}}中拼接字符
    Python 列表切片陷阱:引用、复制与深复制
    基于Python实现的英文文本信息检索系统
    LLMs 蒸馏, 量化精度, 剪枝 模型优化以用于部署 Model optimizations for deployment
    kotlin入门学习文档
    jenkins配置推送java项目
    19种分布式系统设计模式
    npm换更换淘宝镜像
    BENTLY 350015 127610-01数字量输入模块
  • 原文地址:https://blog.csdn.net/lingzhe7428/article/details/127665470