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

    什么是装饰器?

    • 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码修改的提前增加额外功能。
    • 装饰器的返回值也是一个函数对象。
    • 装饰器的作用就是为已经存在的对象添加额外的功能。
    #原函数
    improt time
    
    def foo (): #原函数
        print ("guo hailan")
        time.sleep(2)
    
    def bar():#原函数
        print ("tang qinghua")
        time.sleep(3)

    #需求,在原函数新增一个计时的功能

    实例:

    def foo():
        start = time.time()#获取当前时间    
        print ("guo hailan")
        time.sleep(2)
        end = time.time()
        print ("spend %s"%(end - start))#计算执行用了多长时间
    
    def bar(): 
        start = time.time()()#获取当前时间
        print ("tang qinghua")
        time.sleep(3)
        end = time.time()
        print ("spend %s"%(end - start)
    
    """
    函数虽然实现了功能,但是改变了原来的功能函数,如果是公共函数,修改一旦出错,影响到整个各个功能都出错。
    不允许你动我的原函数,这是封闭原则,还有一个开放原则,虽然你不可以在原功能上修改,但是你可以扩展
    """

    新增功能,重复代码太多

    这样就造成大量雷同的代码,为了减少重复写代码,我们可以这样做,重新定义一个函数,定义一个专门显示时间的函数

    实例:

    def show_time():
        start = time.time()
        foo()#需要计时的函数
        end = time.time()
        print ("spend %s"%(end - start))

    """
    这个函数只能计算foo()函数的时间
    如果要计算bar时间怎么办,又要重建立新的函数呢
    """

    #我们将定义显示时间函数,传一个参数(传入功能函数)计算哪个函数就传入哪个函数名字。

    实例:

    def show_time(f): #f是传入的参数函数
        start = time.time()
        f()  #接受的函数
        end  = time.time()
        print ("spend %s"%(end - start))
     
    show_time(foo)#调用函数
    show_time(bar)
    
    """
    功能是实现了,但是调用方式改变了,之前调用的是foo(),
    所有调用foo()的函数都要跟着改成show_time()
    所有的业务都要跟着改,有点不合理
    """

    问题是怎么不改变调用方式能实现功能。我们的要求是,调用foo()就能实现原函数功能和计时功能。

    我们可以对show_time(foo)赋值,做一个嵌套函数

    def show_time(f): #装饰器函数,(这个函数要放在最前面,因为后面调用的时候需要先存到内存里面)
        def inner():
            start = time.time()
            f()
            end = time.time()
            print ("spend %s"%(end - start))
        return inner #装饰函数返回值是一个函数对象(返回的是inner的内在地址)
    
    foo = show_time(foo) #赋值给foo (这一句要放在原有函数的下面)
    
    
    def foo():
        print ("guo hailan")
        time.sleep()
    foo = show time(foo)
    foo()#执行这个的时候相当于是执行inner函数
    
    '''
    python 提供了一个比较高大上的表示方法@show_time @show_time等价于 foo = show time(foo) @show_time 放在原功能函数的上面 ''' 实例: @show_time() def foo(): print ("guo hailan") time.sleep(3) foo() #函数调用

    功能函数加参数

    实例:

    #功能函数加参数
    def show_time(f): 
        def inner(x,y):
            start = time.time()
            f(x,y)
            end = time.time()
            print ("spend %s"%(end - start))
        return inner 
    
    @show_time() # 等价 add = show_time(add)
    def add(a,b):
        print (a+b)
        time.sleep(3)
    
    add(2,2)

    功能函数传不定长参数

    实例:

    #功能函数传不定长参数
    def show_time(f): 
        def inner(*x,**y):
            start = time.time()
            f(*x,**y)
            end = time.time()
            print ("spend %s"%(end - start))
        return inner 
    @show_time()
    # 等价 add = show_time(add) def add(*a,**b): #功能函数 sums = 0 for i in range(a) sums + = i #等价 sums = sums + i print (sums) time.sleep(3) add(1,3,5,7,9) #这一串传进去给*a

     装饰器加参数

    #装饰器加参数
    def logger(flag="")#加上这个是因为要向外界要个参数进来,默认为空,传true才会打印日志
        def show_time(f): 
            def inner(*x,**y):
                start = time.time()
                f(*x,**y)
                end = time.time()
                print ("spend %s"%(end - start))
                if flag == "true": #必须传true的时候才会打印日志记录
                    print "打印日志记录"
                else:
                    pass
            return inner
        return show_time
    ----------------------------------------------    
    @logger("true")#调用bar的时候需要打印日志,传入参数
    def bar(): #功能函数
        print ("bar....")
        time.sleep(3)
    bar()
    -------------------------------------------
    @logger("eee")#随便传入一个不会打印日志,设置了传true才打印
    def bar(): #功能函数
        print ("bar....")
        time.sleep(3)
    bar()
    ---------------------------------------------
    @logger() #调用add函数的时候不想打印日志,就不传参数
    def add(*a,**b): #功能函数
        sums = 0
        for i in range(a)    
            sums + = i #等价 sums = sums + i
        print (sums)
        time.sleep(3)
    add(1,3,5,7,9)
  • 相关阅读:
    【抄书笔记】《数据压缩导论》
    【举个栗子】我对BP算法的理解
    【举个栗子】我对支持向量机的理解
    linux中监控oracle alert 文件中的ORA-xxx报错信息并发邮件perl脚本
    从dba_hist_sqlstat视图中查找过去时段最占用资源的会话
    AWR信息导出
    Oracle表变化趋势追踪记录 & 表历史 统计信息查看
    oracle-database-maa-best-practices
    详解 db file sequential read 等待事件
    oracle性能优化:Linux环境下合理配置大内存页(HugePage)
  • 原文地址:https://www.cnblogs.com/guog1/p/8278038.html
Copyright © 2011-2022 走看看