av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

這樣用裝飾器,為什么不行?

最近幾周,陸續(xù)收到幾位讀者關(guān)于裝飾器使用的提問,今天統(tǒng)一回復(fù)。

1. 問題

大概問題是這樣,想要自定義一個(gè)Python裝飾器,問我這樣寫裝飾器行不行?如果不行,那又是為什么?

 
 
 
  1. import datetime 
  2. import time 
  3.  
  4. def print_time(g): 
  5.     def f(): 
  6.         print('開始執(zhí)行時(shí)間') 
  7.         print(datetime.datetime.today()) 
  8.          
  9.         g() 
  10.          
  11.         print('結(jié)束時(shí)間') 
  12.         print(datetime.datetime.today()) 
  13.     f() 

下面使用 print_time裝飾函數(shù) foo:

 
 
 
  1. @print_time 
  2. def foo(): 
  3.     time.sleep(2) 
  4.     print('hello world') 

當(dāng)調(diào)用 foo函數(shù)時(shí),拋出如下異常:

 
 
 
  1. foo() 
  2.  
  3. --------------------------------------------------------------------------- 
  4. TypeError                                 Traceback (most recent call last) 
  5.  in  
  6. ----> 1 foo() 
  7.  
  8. TypeError: 'NoneType' object is not callable 

所以,按照如上定義 print_time裝飾器,肯定是不行的。

2. 為什么不行

要想明白為啥不行,首先要知道裝飾器這個(gè)語法的本質(zhì)。其實(shí)很簡(jiǎn)單,@print_time裝飾foo函數(shù)等于:

 
 
 
  1. foo = print_time(foo) 

就是這一行代碼,再也沒有其他。

因?yàn)樯厦娴?print_time 無返回值,所以賦值給 foo 函數(shù)后,foo 函數(shù)變?yōu)?None,所以當(dāng)調(diào)用 foo() 時(shí)拋出 'NoneType' object is not callable

這也就不足為奇了。

3. 應(yīng)該怎么寫

print_time 需要返回一個(gè)函數(shù),這樣賦值給 foo函數(shù)后,正確寫法如下所示:

 
 
 
  1. import datetime 
  2. import time 
  3.  
  4. def print_time(g): 
  5.     def f(): 
  6.         print('開始執(zhí)行時(shí)間') 
  7.         print(datetime.datetime.today()) 
  8.          
  9.         g() 
  10.          
  11.         print('結(jié)束時(shí)間') 
  12.         print(datetime.datetime.today()) 
  13.     return f 

裝飾 foo:

 
 
 
  1. @print_time 
  2. def foo(): 
  3.     time.sleep(2) 
  4.     print('hello world') 

調(diào)用 foo ,運(yùn)行結(jié)果如下:

 
 
 
  1. foo() 
  2.  
  3. 開始執(zhí)行時(shí)間 
  4. 2021-04-02 22:32:49.114124 
  5. hello world 
  6. 結(jié)束時(shí)間 
  7. 2021-04-02 22:32:51.119506 

一切正常

4. 裝飾器好處

上面自定義print_time裝飾器,除了能裝飾foo函數(shù)外,還能裝飾任意其他函數(shù)和類內(nèi)方法。

裝飾任意一個(gè)函數(shù) foo2:

 
 
 
  1. @print_time 
  2. def foo2(): 
  3.   print('this is foo2') 

裝飾類內(nèi)方法 foo3,需要稍微修改原來的print_time:

 
 
 
  1. def print_time(g): 
  2.     def f(*args, **kargs): 
  3.         print('開始執(zhí)行時(shí)間') 
  4.         print(datetime.datetime.today()) 
  5.      
  6.         g(*args, **kargs) 
  7.      
  8.         print('結(jié)束時(shí)間') 
  9.         print(datetime.datetime.today()) 
  10.     return f 

為類MyClass中foo3方法增加print_time裝飾:

 
 
 
  1. class MyClass(object): 
  2.     @print_time 
  3.     def foo3(self): 
  4.         print('this is a method of class') 

執(zhí)行結(jié)果如下:

 
 
 
  1. MyClass().foo3() 
  2.  
  3. 開始執(zhí)行時(shí)間 
  4. 2021-04-02 23:16:32.094025 
  5. this is a method of class 
  6. 結(jié)束時(shí)間 
  7. 2021-04-02 23:16:32.094078 

以上就是裝飾器的通俗解釋,平時(shí)可以多用用,讓我們的代碼更加精煉、可讀。


網(wǎng)頁標(biāo)題:這樣用裝飾器,為什么不行?
分享網(wǎng)址:http://uogjgqi.cn/article/djegsod.html
掃二維碼與項(xiàng)目經(jīng)理溝通

我們?cè)谖⑿派?4小時(shí)期待你的聲音

解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流