zoukankan      html  css  js  c++  java
  • 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()
    

      

  • 相关阅读:
    java实现第二届蓝桥杯四方定理
    java实现第二届蓝桥杯四方定理
    java实现第二届蓝桥杯四方定理
    JPos学习
    Java图片缩略图裁剪水印缩放旋转压缩转格式-Thumbnailator图像处理
    java使用Thumbnailator操作图片
    Python的另一种开发环境--Anaconda中的Spyder
    Java多线程干货系列—(四)volatile关键字
    Java多线程干货系列—(二)synchronized
    Java多线程干货系列—(一)Java多线程基础
  • 原文地址:https://www.cnblogs.com/liang-chen/p/11563827.html
Copyright © 2011-2022 走看看