1. 程式人生 > >函數(三) 裝飾器函數

函數(三) 裝飾器函數

還原 也不能 strong 代碼 per 之前 app imm aaa

裝飾器定義

  裝飾器其實也就是一個函數,一個用來包裝函數的函數,返回一個修改之後的函數值,將新的值賦值原來的函數

2. 裝飾器語法

1、函數名可以當作函數的參數

技術分享
 1 import time
 2 def timmer(func):
 3     #函數名可以當做函數的參數
 4     def inner():
 5         start = time.time()
 6         func()
 7         end = time.time()
 8         print(end - start)      
 9     return inner
10 
11 def hahaha():
12     time.sleep(0.1)
13     print(‘aaaa‘)
14 
15 hahaha()
16 
17 輸出結果
18 aaaa
技術分享

2、假如我們不能修改這個函數的調用方式,也不能修改原代碼,該怎麽做到呢

技術分享
 1 import time
 2 def timmer(func):
 3     #函數名可以當做函數的參數
 4     def inner():
 5         start = time.time()
 6         func()
 7         end = time.time()
 8         print(end - start)
 9     return inner
10 
11 def hahaha():
12     time.sleep(0.1)
13     print(‘aaaa‘)
14 
15 hahaha = timmer(hahaha)       #timmer函數的地址給了hahaha  然後在進行調用
16 hahaha()
17 
18 aaaa
19 0.10033607482910156

# hahaha = timmer(hahaha) #timmer函數的地址給了hahaha
# hahaha() #實際上執行的是timmer

技術分享

3、函數傳參

技術分享
 1 def timmer(func):  #---> hahaha
 2     def inner(*args,**kwargs):         #動態參數接收從kkk傳來的1,2並進行壓縮成元組
 3         #args == (1,2)  kwargs == {}
 4         #*args == 1,2   **kwargs == a =1,b = 2
 5         func(*args,**kwargs)  # ---》kkk   #func把值傳給kkk並還原,實際上就是解壓之前動態參數接收的壓縮的值,返回給kkk函數
 6     return inner
 7 
 8 
 9 def kkk(a,b):
10     print(a)
11 
12 kkk = timmer(kkk)     #timmer函數裏的func是kkk函數,然後返回inner函數給kkk      
13 kkk(1,2)      #kkk函數調用並傳參給inner(動態參數*args),       
14 
15 1
技術分享

參數
#實參:調用函數的時候傳入的參數
#形參
#位置參數:必須傳值

1 def aaa(a,b):
2 print(a,b)
3 aaa(1,2)


#默認參數:可以不傳

1 def bbb(x=10):      #默認參數 沒上傳參數的話用默認的參數,上傳的話會用上傳的參數。
2 print(x)
3 bbb() #x = 10
4 bbb(20) #x = 20

#動態參數

1 def ccc(*args):#1,2,3,4,5     #*args  會將ccc上傳的參數以元組的方式存放 
2 print(args)
3 
4 ccc(1,2,3,4,5)#按位置傳參數

解壓傳參

技術分享
1 def ccc(*args):#1,2,3,4,5
2     print(args)
3 
4 #ccc(1,2,3,4,5)#按位置傳參數
5 
6 t = (1,2,3,4,5)
7 ccc(t) # ((1, 2, 3, 4, 5),)
8 ccc(*t)  #(1, 2, 3, 4, 5)   #解壓
技術分享

按關鍵字傳參

1 def ddd(**kwargs):   #kwargs接收傳參然後以字典的方式存放
2     print(kwargs)
3 
4 ddd(k = ‘a‘,j = ‘b‘)#按關鍵字傳參數

打散賦值

技術分享
 1 def ccc(*args):
 2     print(‘ccc:‘,args)  #(1,2,3,4,5)
 3     def inner(a,b,c,d,e):
 4         print(‘inner‘,a,b,c,d,e)
 5     inner(*args)  #*(1,2,3,4,5)  打散
 6 
 7 def inner(a,b,c,d,e):     #接收解壓的參數然後一一賦值
 8     print(‘inner‘,a,b,c,d,e)
 9 ccc(1,2,3,4,5)
10 inner(1,2,3,4,5)
技術分享

4、語法糖

技術分享
 1 def timmer(func):  #---> jjj
 2     def inner(*args,**kwargs):
 3         ret = func(*args,**kwargs)  # --->ret = jjj()
 4         print(ret)
 5         return ret
 6     return inner
 7 
 8 @timmer  #jjj = timmer(jjj)  語法糖
 9 def jjj():
10     return 123
11 
12 
13 jjj()     #ret = jjj()
14 
15 
16 輸出結果
17 123
技術分享

5、裝飾器函數

#裝飾器的本質 :閉包函數
#功能:就是在不改變原函數調用方式的情況下,在這個函數前後加上擴展功能
def timmer(func):
def inner(*args,**kwargs):
‘‘‘添加函數調用之前的擴展代碼‘‘‘
ret = func(*args,**kwargs)
‘‘‘添加函數調用之後的擴展代碼‘‘‘
return ret
return inner
#設計模式 原則 開放封閉原則
#對擴展是開放的
#對修改是封閉的

6、裝飾器裝飾兩個函數

技術分享
 1 def wrapper(func):#裝飾
 2     def inner(*args,**kwargs):
 3 
 4         ret = func(*args,**kwargs)
 5 
 6         return ret
 7     return inner
 8 
 9 @wrapper        #aaa = wrapper(aaa)
10 def aaa():
11     print(‘asghksdlhf‘)
12 
13 @wrapper        #bbb = wrapper(bbb)
14 def bbb():
15     print(‘asghksdlhf‘)
16 
17 
18 aaa()
19 bbb()
20 
21 
22 #輸出結果:
23 #asghksdlhf
24 #asghksdlhf

函數(三) 裝飾器函數