• python--装饰器


      装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。


    在编程过程中我们会调用许多函数,例如:

    def foo():
        print('this is foo')
    foo()
    def bar():
        print('this is bar')
    bar()
    

      

    但现在我们的需求是得到函数运行所需的时间:

    import time
    def foo():
        start = time.time()
        print("this is foo.")
        time.sleep(2)      #因为此函数运行太快所以加个延时
        end = time.time()
        print('spend %s'%(end-start))
    foo()
    def bar():
        start = time.time()
        print("bar..........")
        time.sleep(2)
        end = time.time()
        print('spend %s' % (end - start))
    bar()

     虽然以上按要求做出来了,但是却有重复的代码,为了解决重复代码,如下:

    import time
    def foo():
        print('foo........')
        time.sleep(2)
    def bar():
        print("bar&&&&&&&&")
        time.sleep(2)
    def show_time(f):
        start = time.time()
        f()
        end = time.time()
        print('spend %s'%(end-start))
    show_time(foo)
    show_time(bar)
    #输出:
    foo........
    spend 2.0001730918884277
    bar&&&&&&&&
    spend 2.000176429748535
    

      这个挺好的,但是吧,如果我们要求最后运行的函数就是本函数比如foo()而不是show_time(foo),那么就:

    import time
    def show_time(f):
        def wrapper():
            start = time.time()
            f()
            end = time.time()
            print('spend %s'%(end-start))
        return wrapper
    def foo():
        print('foo..........')
        time.sleep(2)
    foo = show_time(foo)
    foo()
    #输出:
    foo..........
    spend 2.0007383823394775
    

      python里有个更简便的做法,加@:

    import time
    def show_time(f):
        def wrapper():
            start = time.time()
            f()
            end = time.time()
            print('spend %s'%(end-start))
        return wrapper
    @show_time
    def foo():
        print('foo..........')
        time.sleep(2)
    foo()
    

      带参数的被修饰函数:

    import time
    def show_time(f):
        def wrapper(a,b):
            start = time.time()
            f(a,b)
            end = time.time()
            print('spend %s'%(end-start))
        return wrapper
    @show_time
    def add(a,b):
        print(a+b)
        time.sleep(2)
    add(1,2)
    #输出:3
    可变长加法
    def show_time(f):
        def wrapper(*a,**b):
            start = time.time()
            f(*a,**b)
            end = time.time()
            print('spend %s'%(end-start))
        return wrapper
    @show_time
    def add(*a,**b):
        sum = 0
        for i in a:
            sum+=i
        print(sum)
        time.sleep(2)
    add(1,2,4,5,6)
    #输出:18
    

      装饰器还有更大的灵活性,例如带参数的装饰器:在上面的装饰器调用中,比如@show_time,该装饰器唯一的参数就是执行业务的函数。装饰器的语法允许我们在调用时,提供其它参数,比如@decorator(a)。这样,就为装饰器的编写和使用提供了更大的灵活性。

     

    import time
    def time_logger(flag=0):
        def show_time(f):
            def wrapper():
                start = time.time()
                f()
                end = time.time()
                print('spend %s'%(end-start))
                if flag :
                    print('将这个操作时间写入日志')
            return wrapper
        return show_time
    @time_logger(1)
    def foo():
        print('foo..........')
        time.sleep(2)
    foo()
    

      

  • 相关阅读:
    n8n 基于node 的流程自动化工具
    kubectl-trace 基于bpftrace 的kubernetes 集群性能分析工具
    bcc 基于bpf 分析linux 系统性能的强大工具包
    使用arthas 生成火焰图分析jvm
    openjdk11 stretch基础镜像无法找到对应openjdk dbg 包的问题
    async-profiler 容器使用常见问题
    使用jattach 在host 节点查看容器jvm信息
    使用async-profiler简单分析zeebe 工作流引擎的性能
    minio select api 试用
    使用zeebe DebugHttpExporter 查看zeebe 工作流信息
  • 原文地址:https://www.cnblogs.com/liang-chen/p/11563827.html
Copyright © 2020-2023  润新知