在學習python的過程中按照網上教程的例子寫一個裝飾器(原文https://www.liaoxuefeng.com/wiki/1016959663602400/1017451662295584#0),運行時報錯TypeError: 'NoneType' object is not callable'
代碼如下:
1 def log(func) : 2 def wrapper(): 3 print('time:') 4 func() 5 return wrapper() 6 @log 7 def show(): 8 print('2019') 9 show()
正常的運行結果應該是:
time:
2019
網上搜了一圈都說解決方法是去掉最后函數調用語句的“()”,也沒有其他的說法。但感覺很有問題,所以做個筆記記錄一下。
去掉后發現錯誤確實沒有了,可以正常顯示結果。但這種操作明顯與我們寫代碼的基本常識相違背。(出特殊語法外,一般沒有只通過函數名直接調用函數的)
其實從報錯信息我們就可以猜到是show函數無法被調用,用代碼測試了一下發現確實show變成了一個None類型
def log(func) : def wrapper(): print('time:') func() return wrapper() @log def show(): print('2019') if show is None: print("True")
運行結果:
time: 2019 True
測試后我們發現不僅show已經變成一個None類型,而且調用show的操作就已經被執行了, 實際上根據教程中的寫法在 “@log”語句就已經完成了函數的調用,不用再調用一遍,最后一行代碼實際上是多余的。而且這“@log”種寫法將show這個函數的類型也改變了,原文是“
把@log
放到show()
函數的定義處,相當於執行了語句:
show= log(show)
”后面也無法按照常用方式對這個函數進行調用。具體的機制我暫時還不了解。或者有什么其他的方法來進行重復調用。待以后補充。
文中如有任何表述或者概念有誤,歡迎回復指正!