python高階-閉包-裝飾器

xbhog發表於2020-06-26

閉包內容:

  1. 匿名函式:能夠完成簡單的功能,傳遞這個函式的引用,只有功能

  2. 普通函式:能夠完成複雜的功能,傳遞這個函式的引用,只有功能

  3. 閉包:能夠完成較為複雜的功能,傳遞這個閉包中的函式以及資料,因此傳遞是功能+資料

  4. 物件:能夠完成最複雜的功能,傳遞很多資料+很多功能,因此傳遞的是資料+功能

———————————————————

  1. 對全域性函式進行修改:在函式當中加global,在閉包中外邊中的變數加nonlocal

  2. 閉包定義:有兩個函式巢狀使用,裡面的函式可以使用外面函式所傳輸的引數,最後可傳遞的是裡面函式的結構與資料(個人理解)。

  3. 最後閉包可以在python中引申出裝飾器 ———————————————————

 1 def closure():
 2     # 在函式內部再定義一個函式,
 3     # 並且這個函式用到了外邊函式的變數,那麼將這個函式以及用到的一些變數稱之為閉包
 4     def closure_in(x):
 5         print('---------我是打不死的%s--------' %x)
 6     return closure_in
 7  8 x = closure()
 9 x('小強')
10 11 print('*'*20)
12 # -----加餐---------
13 def closure_1(a,b,c):
14     def closure_on(x):
15         print('-----%s加餐-------' %b)
16         print(a*x + c)
17     return closure_on
18 19 demo = closure_1(2,'小強',3) #傳closure_1函式
20 demo(4) #傳clsure_on函式
21 22 #注:函式不加括號,呼叫的是函式本身【function】;函式加括號,呼叫的是函式的return結果。

 

裝飾器內容:

程式碼要遵守‘開放封閉’原則;對已經寫好的函式遵守封閉,對功能擴充套件遵守開放;

 1 # 裝飾器的作用:為了對原來的程式碼上進行擴充套件
 2 def decoration(func):
 3     def call_func():
 4         print('-------正在裝飾 -------' )
 5         func()
 6     return call_func
 7  8 #@decoration     #--->demo_new = decoration(demo)
 9 def demo():
10    print('demo----')
11 12 demo_new = decoration(demo)
13 demo_new()

 

使用裝飾器來測試一個函式的執行時:

 1 import time
 2 def set_func(func):
 3     def call_func():
 4         start_time = time.time()
 5         func()
 6         stop_func = time.time()
 7         print(‘alltimes is %f’ %(stop_func-start_fun))
 8     return call_func
 9 @set_func
10 def test1():
11     print(‘——-test1———’)    
12 test1()
13 14 #等價於:
15 @set_func==test1 = set_func(test1)
16

 

1. 沒有引數,沒有返回值的函式進行裝飾:
 1 def set_func(func):
 2     def call_func():
 3         print(‘———test2——-’)
 4         print(‘———-test3——’)
 5         func()
 6     return call_func
 7     
 8 @set_func
 9 def test1():
10     print(‘——test1——-   ’)

 

2. 對有引數無返回值的函式進行裝飾:
 1 def set_func(func):
 2     def call_func(a):  #
 3         print(‘———test2——-’)
 4         print(‘———-test3——’)
 5         func(a) #
 6     return call_func
 7     
 8 @set_func
 9 def test1(num):
10     print(‘——test1——- %d    ’ %num)
11 12 test1(100) —->call_func(100)
13 test1(200)——>call_func(200)

 

復現裝飾器原理:

————————————————————————-

只要遇到@函式 裝飾器(這句話),在程式中就已經執行了!!
3. 不定長引數的函式裝飾:
 1 def set_func(func):
 2     def call_func(*args,**kwargs):  #
 3         print(‘———test2——-’)
 4         print(‘———-test3——’)
 5         func(*args,**kwargs) #(拆包)將元祖拆開,每個進行傳輸;
 6         #func(args,kwargs)—>不行,相當於傳遞了兩個引數:一個元祖,一個字典。
 7     return call_func
 8     
 9 @set_func
10 def test1(num,*args,**kwargs):
11     print(‘——test1——- %d    ’ %num)
12     print(‘——test1——-   ’ , args)
13     print(‘——test1——- ’ ,kwargs )
14     
15 test1(100)  
16 test1(100,200)
17 test1(100,200,300,mm=100)

注意:*args儲存不定長引數,以元祖儲存,**kwargs儲存字典形式(mm=...)

4.對應的返回值引數進行裝飾、通用裝飾器:
 1 #通用裝飾器
 2 def set_func(func):
 3     print(“開始進行裝飾———-”)
 4     def call_func(*args,**kwargs):  #
 5         print(‘———test2——-’)
 6         print(‘———-test3——’)
 7         return func(*args,**kwargs) #(拆包)將元祖拆開,每個進行傳輸;如果沒有return ret返回none。
 8         #func(args,kwargs)—>不行,相當於傳遞了兩個引數:一個元祖,一個字典。
 9     return call_func
10     
11 @set_func
12 def test1(num,*args,**kwargs):
13     print(‘——test1——- %d    ’ %num)
14     print(‘——test1——-   ’ , args)
15     print(‘——test1——- ’ ,kwargs )
16     return ‘ok’    #—-返回給上面的func(),然後return func—ret
17     
18 ret = test1(100)
19

 

5. 多個裝飾器對同一個函式進行裝飾:
 1 def add_qx(func):
 2     print(“——開始進行裝飾許可權1———-”)
 3     def call_func(*args,**kwargs):  #
 4         print(‘這是許可權驗證1’)
 5         return func(*args,**kwargs)
 6     return call_func
 7     
 8  9 def add_xx(func):
10     print(“——開始進行裝飾xx功能———-”)
11     def call_func(*args,**kwargs):  #
12         print(‘這是xx許可權驗證’)
13         return func(*args,**kwargs)
14     return call_func
15     
16 @add_qx
17 @add_xx
18 def test1():
19     print(‘——test1——-’) 
20 21 test1()
22

 

首先執行第一個,但是第一個裝飾器下面不是函式(裝飾器原則:下面必須是函式,否則不執行),所以第一個函式先等待,等第二個裝飾器執行後形成函式在交給第一個裝飾器;所以執行結果是:

  1. 開始進行裝飾xx的功能,

  2. 開始進行裝飾許可權1,

  3. 這是許可權驗證1,

  4. 這是xx許可權驗證,

  5. ——-test1——-,

——————裝飾器練習—————- 輸出格式:<td><h1>haha</h1></td>

 1 def set_func_1(func):
 2     def call_func():
 3         return ‘<h1>’ + func() + ’</h1> 4     return call_func
 5     
 6  7 def set_func_2(func):
 8     def call_func():
 9         return ‘<td>’ + func() + ’</td>10     return call_func
11     
12 @set_func_1()
13 @set_func_2()
14 def get_str():
15     return ‘haha’
16     
17 print(get_str()) 

18 最後執行的效果: <h1><td>haha</td></h1>
6. 用類對函式進行裝飾(瞭解):
 1 class Test(object):
 2     def __init__(self,func):
 3         self.func = fun
 4         
 5     def __call__(self):
 6         print(‘這裡是裝飾器的功能。。。。’)
 7         return self.func()
 8         
 9 @Test
10 def get_str():
11     return ‘haha’
12     
13 print(get_str())

 

以上就是裝飾器與閉包的全部內容,希望有所收穫,如果有錯誤,希望指出,感謝!!

 

相關文章