匿名函數:可以完成簡單的功能,傳遞這個函數的引用,只有功能python
普通函數:可以完成複雜的功能,傳遞這個函數的引用,只有功能閉包
閉包:可以完成較爲複雜的功能,傳遞這個閉包中的函數以及數據,所以傳遞是功能+數據函數
對象:可以完成最複雜的功能,傳遞不少數據+不少功能,所以傳遞的是數據+功能測試
———————————————————spa
對全局函數進行修改:在函數當中加global,在閉包中外邊中的變量加nonlocalcode
閉包定義:有兩個函數嵌套使用,裏面的函數可使用外面函數所傳輸的參數,最後可傳遞的是裏面函數的結構與數據(我的理解)。對象
blog
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結果。
代碼要遵照‘開放封閉’原則;對已經寫好的函數遵照封閉,對功能擴展遵照開放;get
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()
使用裝飾器來測試一個函數的運行時:it
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 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——- ’)
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)
復現裝飾器原理:
————————————————————————-
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=...)
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
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
首先執行第一個,可是第一個裝飾器下面不是函數(裝飾器原則:下面必須是函數,不然不執行),因此第一個函數先等待,等第二個裝飾器執行後造成函數在交給第一個裝飾器;因此運行結果是:
開始進行裝飾xx的功能,
開始進行裝飾權限1,
這是權限驗證1,
這是xx權限驗證,
——-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>
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())