zoukankan      html  css  js  c++  java
  • 3、三大神器 -装饰器

    1)、函数的特性
    • 函数作为变def test1(x):
    def test1(x):
        return x+1
    
    a =test1(1)
    • 函数作为参数(其他函数的入参)
    def test1(x):
        print(x+1)
    
    def test2(f):  #其他的函数f作为入参
        f(3) 
    
    test2(test1)
    • 函数作为返回值
    def test1(x):
        print(x+1)
    
    def test2():
        return test1 #返回test1()函数
     
    • 函数嵌套,跨域调用
    def test2():
        a =1
    
        #内部嵌套函数
        def test3():
            print(a) #跨域调用
    
        test3()
    执行过程:(也可以通过调试的方式查看执行过程)
        执行a =1
        定义test3()函数(但是不执行函数中的步骤,因为没有调用函数)
        执行函数test3()
            执行test3()中的print(a)语句
     
    2)、闭包
        装饰器就是通过闭包实现的,闭包:函数内部嵌套定义内部函数 +内部函数使用外部函数的的变量
     
    闭包的实现:
    def outer(x):
    
        def inner():  #内部嵌套函数
            print(x) #跨域调用,内部函数调用外部函数的入参
    
        return inner  #函数作为返回函数,一定注意::不能return inner() ××
    
    #调用函数
    inner_func =outer(100) #调用外部函数,传入外部入参x=100。将inner()函数赋值给aa 即aa就是函数inner() ==闭包
    inner_func() 
    执行过程:
        条用outer()外部函数,外部入参x=100
        进行outer()内部,定义def inner()
        返回 inner内部函数
        将inner函数赋值给inner_func变量
        调用inner_func()相当于调用内部函数 inner() ,执行print(x)

    2.1)、闭包进阶--将其他函数作为入参传入外部函函数   

    def test():
        print(100)
    
    def outer(x):
    
        def inner(): #内部嵌套函数
            x()  #跨域调用外部入参x()
    
        return inner #返回闭包 内部函数inner()
    
    #调用函数
    inner_func =outer(test)
    inner_func()
    执行过程:
        调用外部函数outer()
        返回内部函数inner()
        将闭包 内部函数inner()赋值给inner_func(),所以inner_func变量就相当于内部函数inner()
        执行inner_func()即执行inner()函数, print(100)
     
    这样,执行外部函数outer()+执行闭包 内部函数,就相当于执行了test()函数
     
    3)、装饰器
     
    当我们想执行outer(func)的结果函数时,其实就是对func()函数进行装饰,只需要@out
     
    装饰器函数将函数作为入参+返回内部函数+内部函数调用入参函数执行
    def outer(func):
    
        print('给需要装饰的函数,装饰点其他功能')
    
        def inner(): #内部嵌套函数
            func() #跨域调用外部入参x()
    
        return inner #返回闭包 内部函数inner()
    
    @outer
    def test():
        print(100)
    
    if __name__ =='__main__':
        test()



    -----执行结果-----

    给需要装饰的函数,装饰点其他功能
    100

    执行过程分析:
        执行test()就相当于将test()作为入参传入outer(),执行outer()函数
        执行print('给需要装饰的函数,装饰点其他功能'
        定义inner
        执行return inner 返回inner()函数
        执行inner()函数,执行func() 即执行test()
        执行print(100)
     
    实例:打印每个方法的执行时间
    def showtime(func):
    
        import time
        begtime =time.time() #被装饰函数执行前,记录开始时间
    
        def inner(): #内部函数定义
            func() #内部函数中执行被装饰函数
    
            endtime =time.time() #被装饰函数执行结束,显示结束时间
            print(endtime-begtime) #显示函数执行时间
    
        return inner #装饰器返回内部函数
    
    
    @showtime
    def test1():
        import time
        time.sleep(2)
    
    -----执行结果----
    2.0101544857025146
    4)、装饰器进阶--如果被装饰的函数需要入参
     
         --解决办法:给inner(*args,**kwargs) 传入万能入参,将万能入参传入的func(*args,**kwargs) 。
                    必须使用万能入参,因为我们也不知道被装饰函数func()的入参到底是什么
    ef showtime(func):
    
        import time
        begtime =time.time() #被装饰函数执行前,记录开始时间
    
        def inner(*args,**kwargs): #内部函数定义
            func(*args,**kwargs) #内部函数中执行被装饰函数
    
            endtime =time.time() #被装饰函数执行结束,显示结束时间
            print(endtime-begtime) #显示函数执行时间
    
        return inner #装饰器返回内部函数
    
    
    @showtime
    def test1(name):
        import time
        time.sleep(2)
        print('函数的名称是:',name)

    备注: 本文有参考:上海-悠悠等他人博客

  • 相关阅读:
    get请求中文乱码问题
    JDBC
    SpringSecurity
    IDEA中创建项目
    Vue路由传参的几种方式
    vue-cli搭建与使用
    docker发布springboot项目
    css伪类的使用
    java实体类序列化与反序列化
    docker网络
  • 原文地址:https://www.cnblogs.com/jesse-zhao/p/14528046.html
Copyright © 2011-2022 走看看