成人免费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

2015-08-06 10:19:19

編程腦子

2011-07-21 11:11:10

Scrum

2010-04-06 12:59:18

MVC

2019-08-15 16:48:30

2015-09-07 09:53:02

Objective-CRuntime

2022-09-24 09:52:42

TopicQueuekafka

2021-01-20 12:44:22

JAVA編程語言軟件

2021-01-20 12:43:07

編程語言Java

2021-02-01 15:51:45

數據可視化圖表項目

2012-04-11 09:19:08

Haskell編程

2017-06-19 13:10:59

大數據大數據平臺架構

2017-06-20 09:54:18

大數據架構數據分析

2023-02-07 07:47:52

Python裝飾器函數

2021-04-09 08:23:30

Css前端加載動畫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩欧美国产一区二区 | 久久精品手机视频 | 亚洲精品一区二区 | 日韩精品一区二区三区四区视频 | 国产精品视频在线观看 | 亚洲成人播放器 | 五月婷亚洲 | a级在线免费 | 久久久久久91 | 成年无码av片在线 | 国产一区二区三区视频 | 九九热精品在线视频 | 国产精品视频一区二区三区 | 免费观看一级特黄欧美大片 | 国产99久久精品一区二区300 | 国产中文字幕在线观看 | 不用播放器看的av | 国产精品国色综合久久 | 欧美精品欧美精品系列 | 亚洲精品久久久一区二区三区 | 成人网av | www日日日| 国产中文视频 | 国产91精品网站 | 国产精品久久久久久久久久久久 | 在线亚洲人成电影网站色www | 天天干天天爱天天 | 亚洲aⅴ| 天天躁日日躁狠狠躁2018小说 | 午夜不卡一区二区 | 久久精品一 | 香蕉超碰 | 久久久久久99 | 国产免费黄网 | 亚洲精品小视频在线观看 | 久久久精品视频免费看 | 日本高清中文字幕 | 欧美不卡一区二区三区 | 日韩视频三区 | 人人九九精 | 特黄一级 |