成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

最近幾周,陸續收到幾位讀者關于裝飾器使用的提問,今天統一回復。

[[391225]]

1. 問題

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

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

下面使用 print_time裝飾函數 foo:

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

當調用 foo函數時,拋出如下異常:

  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. 為什么不行

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

  1. foo = print_time(foo) 

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

因為上面的 print_time 無返回值,所以賦值給 foo 函數后,foo 函數變為 None,所以當調用 foo() 時拋出 'NoneType' object is not callable

這也就不足為奇了。

3. 應該怎么寫

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

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

裝飾 foo:

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

調用 foo ,運行結果如下:

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

一切正常

4. 裝飾器好處

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

裝飾任意一個函數 foo2:

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

裝飾類內方法 foo3,需要稍微修改原來的print_time:

  1. def print_time(g): 
  2.     def f(*args, **kargs): 
  3.         print('開始執行時間') 
  4.         print(datetime.datetime.today()) 
  5.      
  6.         g(*args, **kargs) 
  7.      
  8.         print('結束時間') 
  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') 

執行結果如下:

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

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

 

責任編輯:趙寧寧 來源: Python與算法社區
相關推薦

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開發函數

2021-07-21 09:35:36

switchbreakJava

2021-05-08 08:55:54

CPUIBMIntel

2010-04-06 12:59:18

MVC

2015-08-06 10:19:19

編程腦子

2011-07-21 11:11:10

Scrum

2019-08-15 16:48:30

2021-01-20 12:44:22

JAVA編程語言軟件

2021-01-20 12:43:07

編程語言Java

2015-09-07 09:53:02

Objective-CRuntime

2022-09-24 09:52:42

TopicQueuekafka

2021-02-01 15:51:45

數據可視化圖表項目

2017-06-19 13:10:59

大數據大數據平臺架構

2017-06-20 09:54:18

大數據架構數據分析

2012-04-11 09:19:08

Haskell編程

2023-02-07 07:47:52

Python裝飾器函數

2010-02-01 17:50:32

Python裝飾器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本天堂视频在线观看 | 亚洲国产欧美一区 | 亚洲国产高清高潮精品美女 | 99re在线视频观看 | 91久久国产精品 | 国产精品揄拍一区二区 | 日韩一二三| 91精品久久久久久久久久 | 欧美日韩久久精品 | 99精品免费视频 | 亚洲欧美在线视频 | 亚洲成人精选 | 日韩视频中文字幕 | av在线免费观看不卡 | 久久成人免费视频 | 免费一区二区三区 | 97av视频在线 | 成人av观看 | 欧美日韩国产精品一区二区 | 黄色大片在线免费观看 | 七七婷婷婷婷精品国产 | 亚洲国产情侣自拍 | 婷婷综合| 欧美无乱码久久久免费午夜一区 | 蜜桃一区二区三区 | 一区二区三区在线观看视频 | 国产欧美精品区一区二区三区 | 日韩欧美亚洲综合 | 99在线观看视频 | 亚洲精品在线免费看 | 国产成人免费一区二区60岁 | 狠狠色狠狠色综合系列 | 手机av在线 | 精品自拍视频在线观看 | 久草视频2| 国产日韩欧美 | 午夜精品视频 | 国产一区二区在线播放 | 黄色日本片 | 成人伊人 | 国产一区二区三区四区三区四 |