閉包 與 裝飾器

  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
相關文章
相關標籤/搜索