• python中装饰器使用


    装饰器是对已有的模块进行装饰(添加新功能)的函数。

    现有一段代码:

    1 import time
    2 def func1():
    3     time.sleep(3)
    4     print("in the func1")
    5 def func2():
    6     time.sleep(2)
    7     print("in the func2")
    8 func1()
    9 func2()

    现在需要增加func1和func2的功能,计算段代码的运行时间。

    思路1:修改函数内的代码:

     1 import time
     2 def func1():
     3     start_time = time.time()
     4     time.sleep(3)
     5     print("in the func1")
     6     stop_time = time.time()
     7     print("this program run %ss"%(stop_time-start_time))
     8 def func2():
     9     start_time = time.time()
    10     time.sleep(2)
    11     print("in the func2")
    12     stop_time = time.time()
    13     print("this program run %ss"%(stop_time-start_time))
    14 func1()
    15 func2()

    每个函数都添加了红色的代码段,如果需要改的func较多时,该方法明显不适用。并且违反了为函数添加附加功能时的原则1:不能修改被装饰函数的源代码。

    思路2:增加新函数:

     1 import time
     2 def func1():
     3     time.sleep(3)
     4     print("in the func1")
     5 def func2():
     6     time.sleep(2)
     7     print("in the func2")
     8 def func_new1():
     9     start_time = time.time()
    10     func1()
    11     stop_time =time.time()
    12     print("this program run %ss"%(stop_time-start_time))
    13 def func_new2():
    14     start_time = time.time()
    15     func2()
    16     stop_time =time.time()
    17     print("this program run %ss"%(stop_time-start_time))
    18 func_new1()
    19 func_new2()

    该方法增加了新函数,将原有函数引用至新函数中。但问题又来了,需要改主程序中对原有函数的引用方法,违反了并且违反了为函数添加附加功能时的原则2:不能修改被装饰函数的调用方式。

    此刻,我们需要新的知识储备来完善对装饰器的理解

    1.函数的嵌套

    2.高阶函数

    3.函数——变量的关系

    高阶函数+嵌套函数===》装饰器

    插入名词的解释!!

    高阶函数:满足下列原则之一的就是高阶函数:

      a.把一个函数名当作实参传给另一个函数的函数。

     1 import time
     2 def bar():
     3     time.sleep(3)
     4     print("in the bar")
     5 def test(func):
     6     start_time = time.time()
     7     func()
     8     stop_time = time.time()
     9     print("the func run time is %s"%(stop_time-start_time))
    10 test(bar)

    在此函数中,bar作为实参被传递给形参func,test(bar)。通过test()函数为bar()增加了新功能,且没有改变bar()的源代码。但改变了原有bar()的调用方式。

    实现了不修改被装饰函数的源代码情况下为其添加新功能的目的。

      b.返回值中包含函数名

     1 import time
     2 def bar():
     3     time.sleep(3)
     4     print("in the bar")
     5 def test(func):
     6     print(func)
     7     print()
     8     return func
     9 bar = test(bar)
    10 bar()

    在此代码中,原有函数bar(),然后bar作为函数名被传给新增函数test(),随后又作为该函数的返回值。相当与给bar()增加了新的功能(显示bar()的内存地址),但没有改变bar()的调用方式。

    嵌套函数:在函数体内声明的函数(必须是声明,不能是调用)

    def test1():
        print("in the test1")
        def test2():
            print("in the test2")
        test2()
    test1()

    test2()是在test1()中声明的函数

    将高阶函数与嵌套函数结合,

     1 import time
     2 def timmer(func):
     3     def deco():
     4         start_time = time.time()
     5         func()
     6         stop_time = time.time()
     7         print("the func run time is %ss"%(stop_time-start_time))
     8     return deco
     9 @timmer    #等于在func1被调用前加上func1=timmer(func1)
    10 def func1():
    11     time.sleep(3)
    12     print("in the func1")
    13 @timmer
    14 def func2():
    15     time.sleep(2)
    16     print("in the func2")
    17 func1()
    18 func2()

    其中@timmer = func1= timmer(func1),就是在被装饰的函数前加上装饰器的名称。在没有改变被装饰代码的源代码及调用方式的情况下增加了其功能。

  • 相关阅读:
    【NOIP2009提高组】最优贸易
    matlab数字图像处理-给图片加入可视水印信息
    数字水印技术
    matlab数据插值
    matlab中的多项式计算
    python中圆周率的计算
    python中random库的使用
    python的循环结构
    python身体指数BMI
    python程序控制--分支结构
  • 原文地址:https://www.cnblogs.com/yinsedeyinse/p/9893650.html
Copyright © 2020-2023  润新知