zoukankan      html  css  js  c++  java
  • Python之装饰器

    一、简单的装饰器

    1.为什么要使用装饰器呢?

      装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

      装饰器的本质:就是一个闭包函数

    那么我们先来看一个简单的装饰器:实现计算每个函数的执行时间的功能

    import time 
    def  wrapper(func):
            def inner():
                  start=time.time()
                  func()
                  end=time.time()
                  print(end-start)
            return inner 
        
    def  hahaha():
            time.sleep(1)
            print('aaaaa')
    hahaha=wrapper(hahaha)
    hahaha()    

    上面的功能有点不简介,不完美,看一下Python的语法糖。

    import time
    def wrapper(func):
            def inner():
                   start=time.time()
                   func()
                   end=time.time()
                   print(end-start)
            return inner
    @wrapper
    def  kkk():#相当于kkk=wrapper(kkk)
        print('aaaaa')
    kkk()             

    以上的装饰器都是不带参数的函数,现在装饰一个带参数的该怎么办呢?

    import time
    def timer(func):
        def inner(*args,**kwargs):
            start = time.time()
            re = func(*args,**kwargs)
            end=time.time()
            print(end- start)
            return re
        return inner
    
    @timer   #==> func1 = timer(func1)
    def func1(a,b):
        print('in func1')
        print(a,b)
    
    @timer   #==> func1 = timer(func1)
    def func2(a):
        print('in func2 and get a:%s'%(a))
        return 'fun2 over'
    
    func1(1,2)
    print(func2('aaaaaa'))
    原函数带多个参数的装饰器
    import time
    def timer(func):
        def inner(*args,**kwargs):
            start = time.time()
            re = func(*args,**kwargs)
            end=time.time()
            print(end - start)
            return re
        return inner
    
    @timer   #==> func1 = timer(func1)
    def jjj(a):
        print('in jjj and get a:%s'%(a))
        return 'fun2 over'
    
    jjj('aaaaaa')
    print(jjj('aaaaaa'))
    带返回值的装饰器

    二,装饰器的固定结构

    import time
    def wrapper(func):  # 装饰器
        def inner(*args, **kwargs):
            '''函数执行之前的内容扩展'''
            ret = func(*args, **kwargs)
             '''函数执行之前的内容扩展'''
            return ret
        return inner
    
    @wrapper  # =====>aaa=timmer(aaa)
    def aaa():
        time.sleep(1)
        print('fdfgdg')
    aaa()

    三,带参数的装饰器

    带参数的装饰器:就是给装饰器传参

            用处:就是当加了很多装饰器的时候,现在忽然又不想加装饰器了,想把装饰器给去掉了,但是那么多的代码,一个一个的去闲的麻烦,那么,我们可以利用带参数的装饰器去装饰它,这就他就像一个开关一样,要的时候就调用了,不用的时候就去掉了。给装饰器里面传个参数,那么那个语法糖也要带个括号。在语法糖的括号内传参。在这里,我们可以用三层嵌套,弄一个标识为去标识。如下面的代码示例

    # 带参数的装饰器:(相当于开关)为了给装饰器传参
    # F=True#为True时就把装饰器给加上了
    F=False#为False时就把装饰器给去掉了
    def outer(flag):
        def wrapper(func):
            def inner(*args,**kwargs):
                if flag:
                    print('before')
                    ret=func(*args,**kwargs)
                    print('after')
                else:
                    ret = func(*args, **kwargs)
                return ret
            return inner
        return wrapper
    
    @outer(F)#@wrapper
    def hahaha():
        print('hahaha')
    
    @outer(F)
    def shuangwaiwai():
        print('shuangwaiwai')
    
    hahaha()
    shuangwaiwai()
    给装饰器加参数

    四,多个装饰器装饰一个函数

    def qqqxing(fun):
        def inner(*args,**kwargs):
            print('in qqxing: before')
            ret = fun(*args,**kwargs)
            print('in qqxing: after')
            return ret
        return inner
    
    def pipixia(fun):
        def inner(*args,**kwargs):
            print('in pipixia: before')
            ret = fun(*args,**kwargs)
            print('in pipixia: after')
            return ret
        return inner
    @qqqxing
    @pipixia
    def dapangxie():
        print('饿了吗')
    dapangxie()
    多个装饰器装饰一个函数

    五、统计多少个函数被装饰了的小应用

    l=[]
    def wrapper(fun):
        l.append(fun)#统计当前程序中有多少个函数被装饰了
        def inner(*args,**kwargs):
            # l.append(fun)#统计本次程序执行有多少个带装饰器的函数被调用了
            ret = fun(*args,**kwargs)
            return ret
        return inner
    
    @wrapper
    def f1():
        print('in f1')
    
    @wrapper
    def f2():
        print('in f2')
    
    @wrapper
    def f3():
        print('in f3')
    print(l)
  • 相关阅读:
    spark 读取mongodb失败,报executor time out 和GC overhead limit exceeded 异常
    在zepplin 使用spark sql 查询mongodb的数据
    Unable to query from Mongodb from Zeppelin using spark
    spark 与zepplin 版本兼容
    kafka 新旧消费者的区别
    kafka 新生产者发送消息流程
    spark ui acl 不生效的问题分析
    python中if __name__ == '__main__': 的解析
    深入C++的new
    NSSplitView
  • 原文地址:https://www.cnblogs.com/zhouxinyu/p/8983920.html
Copyright © 2011-2022 走看看