自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

開發(fā) 前端
最近幾周,陸續(xù)收到幾位讀者關(guān)于裝飾器使用的提問:想要自定義一個Python裝飾器,問我這樣寫裝飾器行不行?如果不行,那又是為什么?今天統(tǒng)一回復(fù)。

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

[[391225]]

1. 問題

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

  1. import datetime 
  2. import time 
  3.  
  4. def print_time(g): 
  5.     def f(): 
  6.         print('開始執(zhí)行時間') 
  7.         print(datetime.datetime.today()) 
  8.          
  9.         g() 
  10.          
  11.         print('結(jié)束時間') 
  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ù)時,拋出如下異常:

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

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

2. 為什么不行

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

  1. foo = print_time(foo) 

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

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

這也就不足為奇了。

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

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

  1. import datetime 
  2. import time 
  3.  
  4. def print_time(g): 
  5.     def f(): 
  6.         print('開始執(zhí)行時間') 
  7.         print(datetime.datetime.today()) 
  8.          
  9.         g() 
  10.          
  11.         print('結(jié)束時間') 
  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 ,運行結(jié)果如下:

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

一切正常

4. 裝飾器好處

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

裝飾任意一個函數(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í)行時間') 
  4.         print(datetime.datetime.today()) 
  5.      
  6.         g(*args, **kargs) 
  7.      
  8.         print('結(jié)束時間') 
  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í)行時間 
  4. 2021-04-02 23:16:32.094025 
  5. this is a method of class 
  6. 結(jié)束時間 
  7. 2021-04-02 23:16:32.094078 

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

 

責(zé)任編輯:趙寧寧 來源: Python與算法社區(qū)
相關(guān)推薦

2017-07-07 17:01:32

裝飾器代碼Python

2023-06-26 07:31:29

中文編程編碼

2013-01-22 09:35:27

Hadoop存儲

2021-02-14 13:38:17

Python開發(fā)函數(shù)

2021-05-08 08:55:54

CPUIBMIntel

2021-07-21 09:35:36

switchbreakJava

2015-08-06 10:19:19

編程腦子

2011-07-21 11:11:10

Scrum

2010-04-06 12:59:18

MVC

2021-01-20 12:44:22

JAVA編程語言軟件

2021-01-20 12:43:07

編程語言Java

2019-08-15 16:48:30

2022-09-24 09:52:42

TopicQueuekafka

2015-09-07 09:53:02

Objective-CRuntime

2010-02-01 17:50:32

Python裝飾器

2021-02-01 15:51:45

數(shù)據(jù)可視化圖表項目

2017-06-19 13:10:59

大數(shù)據(jù)大數(shù)據(jù)平臺架構(gòu)

2012-04-11 09:19:08

Haskell編程

2017-06-20 09:54:18

大數(shù)據(jù)架構(gòu)數(shù)據(jù)分析

2022-01-06 07:34:46

點贊
收藏

51CTO技術(shù)棧公眾號