闭包 与 装饰器

  1. 函数参数
    1. 函数名存储了函数所在的空间地址
    2. 函数名+ () 到函数所在的空间执行里面的代码
  2. 闭包:
    1. 发生函数嵌套
    2. 外层函数的返回值是内层函数的函数名(地址/引用)
    3. 外层函数有参数(内层函数使用到)
    4. 节省系统资源  提高代码复用率的一种特殊语法
    5. 语法格式
      1. def  外层函数(参数):
            def 内层函数():
                pass
            return 内层函数
    6. 闭包流程
      1. 执行第五行 调用func_out 
      2. 执行2,3 行 func_in函数 只定以不执行  开辟一个空间 暂且定为   0x11(),所以func_in=0x11
      3. 执行第四行  返回func_in 也就是0x11
      4. 然后到第五行 usa_rate= func_in= 0x11
      5. 执行第六行 0x11(100)  =  fun_in()
      6. 执行2,3 行代码
        1.   
          1 1.def func_out(rate):
          2 2.   def func_in(money):
          3 3.        print(rate * money)
          4  
          5 4.    return func_in
          6  
          7 5.usa_rate = func_out(0.7)
          8 6.usa_rate(100)
        
 
 
  • nonlocal    ------   声明外层函数的变量
  1. 装饰器  
    1. 在不改变原有代码的前提下  还可以给函数增加新的功能
    2. 使用方法
      1. @新加功能的函数名
      2. 装饰器下面正好是函数
      3. 自动执行 login = func_out(login)
      4. 执行流程
        1. 执行第六行,首先装饰器会自动执行一句话 login = func_out(login)
        2. 把7,8行代码开辟一个空间地址暂且叫做0x22, 当作参数传给第一行func
        3. 执行第一行   0x22传递给func
        4. 2,3,4函数只定以不执行开辟一个空间地址  暂且是 0x11
        5. 执行第五行  返回func_in  = =0x11 给函数调用者,  也就是 login = func_in== 0x11
        6. 然后执行login() == 0x11()==func_in(),到2,3,4代码  
        7. 第四行  func() == login ==0x22=7,8行代码
      5. *** 执行流程结论***
        1. func ==> 原始login  也就是0x22
        2. 新的login()0x11 ==>func_in()
        3. 1.def func_out(func):
          2.    def func_in():
          3.        print("验证")
          4.        func()
          5.    return func_in
          6.@func_out
          7.def login():
          8.    print("登录")
          9.login()
 
  1. 通用版装饰器
 
def func_out(func):
    def func_in(*args,**kwargs):
        return func(*args,**kwargs)
 
    return func_in
 
@func_out
def login(*args,**kwargs):
    print(args)
    print(kwargs)
 
 
 
login(10,30,age = "123",name = "qwe")
  1. 多重装饰器
    1. 执行流程
      1.  
        1.def func_out01(func01):
        2.    print("func_out01 is show")
        3.    def func_in01():
        4.        print("func01 is show")
        5.        func01()
        6.    return func_in01
        7.def func_out02(func02):
        8.    print("func_out02 is show")
        9.    def func_in02():
        10.        print("func02 is show")
        11.        func02()
        12.   return func_in02
        13.@func_out02
        14.@func_out01
        15.def login():
        16.    print('login is show')
        17.login()
         
        答案:
        func_out01 is show
        func_out02 is show
        func02 is show
        func01 is show
        login is show
         
         
      2. 首先执行13行 装饰器func_out02下面不是函数,所以执行14行,
      3. 把15.16行开辟一个空间暂且定义为0x11 ,把0x11当作参数传递给func01暂且存起来
      4. 执行func_out01,自动执行login = func_out(login)  login = 0x11 = func01
      5. 执行第二行  得出第一个结果 --- func_out01  is show
      6. 3,4,5只定以不执行 开辟一个空间 暂且定义以为  0x22
      7. 返回 0x22    新login = 0x22 = func_in01
      8. 14行变为一个函数
      9. 执行装饰器13行  自动执行 0x22=func_in01 == func_out02(0x22)
      10. 执行10行  func_in01 = func02 = 0x22   得出第二个结果 ----- func_out02  is show
      11. 把9,10,11  封装起来  开辟一个空间 称为  0x33 
      12. 执行12行  返回给函数调用者  login = func_in02()
      13. 这时候执行login()
      14. 执行9,10,11 行代码得出 第三个结果---  func02  is show
      15. 执行11行  fun02() = func_in01()-----得出func01  is  show
      16. 执行fun01()  得出  ==  login   is   show       fun01() = login
 

猜你喜欢

转载自www.cnblogs.com/ZT-GJ/p/9693458.html