zoukankan      html  css  js  c++  java
  • Python自学之乐-装饰器浅谈

    以前学过点 面向对象的知识,我感觉这之间是有关联的,比如说装饰器的第一个要素是对被装饰的函数的封闭性,不允许更改;第二个就是对装饰器本oj身的可扩展性。

    装饰器要点:高阶函数+嵌套函数=装饰器

    需要掌握的知识点:1、函数即变量

    2、高阶函数(函数的参数也是函数)

    3、嵌套函数

    装饰器一:装饰器不带参数,被装饰的函数也不带参数

    简单的需求:现有两个简单的打印内容的函数,现在需要在不改变两个函数源代码的情况下统计每个函数运行时间

    import time
    def timer(func):#用到高阶函数
    def deco():#用到函数嵌套
    start_time = time.time()
    func()
    stop_time = time.time()
    print("the func run %s" %(stop_time-start_time))
    return deco
    @timer
    def test1():
    time.sleep(3)
    print("i am test1")
    @timer
    def test2():
    time.sleep(3)
    print("i am test2")
    test1()
    test2()
    执行顺序:首先程序自上往下走,走到定义的timer函数的时候会跳到@timer处,检测到timer被作为装饰器了,系统会去搜索哪些地方使用了timer作为装饰器,搜索完成后,执行timer;紧接着执行我们调用的test1(),因为test1被timer装饰了,所以会先去执行装饰器,在装饰器内部执行到func()时,此时func()就是test1()! test2()也是一样
    装饰器的效果就是:没有改变原来函数的源代码和函数调用方式,又给函数增加了新功能

    装饰器二:被装饰函数带参数

    上面的代码被装饰的函数都没有参数,显然功能很局限,加上两个参数我们再看一看
    def timer(func):
    def deco(*args,**kwargs):
    start_time = time.time()
    func(*args,**kwargs)
    stop_time = time.time()
    print("the func run %s" %(stop_time-start_time))
    return deco
    @timer
    def test1():
    time.sleep(3)
    print("i am test1")
    @timer
    def test2(name,age):
    time.sleep(3)
    print("i am test2",name,age)
    test1()
    test2("clark",20)
    执行结果:

    i am test1
    the func run 3.010805368423462
    i am test2 clark 20
    the func run 3.010805130004883

    总结:我们看到,我们的装饰器加入了*args **kwargs参数的固定写法,无论被装饰的函数有参数(test2)或者没有参数(test1),最终都可以实现装饰效果,而且两个函数本身正常运行

    装饰器三:被装饰函数有返回值
    #Author:clark
    import time
    def timer(func):#用到高阶函数
    def deco(*args,**kwargs):#用到函数嵌套
    start_time = time.time()
    val = func(*args,**kwargs)
    stop_time = time.time()
    print("the func run %s" %(stop_time-start_time))
    return val
    return deco
    @timer
    def test1():
    time.sleep(3)
    print("i am test1")
    @timer
    def test2(x):
    time.sleep(3)
    print("i am test2")
    return x*x
    test1()
    print(test2(3))
    执行结果:

    i am test1
    the func run 3.0068066120147705
    i am test2
    the func run 3.0043063163757324
    9

     总结:test2是有返回值的,所以我们需要在装饰器内部定义一个变量来接收返回值,再return这个变量,最终结果也是有无返回值的函数都正常运行,并且有返回值的函数,返回值也是正确的返回了


    装饰器四:装饰器本身带参数



  • 相关阅读:
    Java实现 LeetCode 680 验证回文字符串 Ⅱ(暴力)
    Java实现 LeetCode 680 验证回文字符串 Ⅱ(暴力)
    Java实现 LeetCode 680 验证回文字符串 Ⅱ(暴力)
    PHP import_request_variables() 函数
    PHP gettype() 函数
    PHP get_resource_type() 函数
    PHP get_defined_vars() 函数
    PHP floatval()、doubleval () 函数
    反射的相关知识点
    泛型知识
  • 原文地址:https://www.cnblogs.com/clarkxhb/p/7376643.html
Copyright © 2011-2022 走看看