python装饰器副作用_对Python 装饰器的理解心得
0x00000000030A40D0位置(這個位置應該是指內存位置)存有一個function(方法)叫target;在 target后面加上(),表示調用該方法,即輸入target(),“大腦”便按照target方法所寫的代 碼逐條執行,于是打印出了target字符串,并且“大腦”明白在0x00000000030A4268位置有一 個叫returnme的方法;因為target對象調用后是會返回一個returnme方法,并且方法是可以被調用的,因 此你可以直接這樣書寫target()(),“大腦”會逐條執行target中的代碼,然后return一個 returnme,因為多加了一個(),表示要對返回的returnme進行調用,于是再次逐條執行returnme中的代碼 ,最后便能看到15、16的打印結果;而returnme方法是沒有返回任何可調用的對象,因此當輸入 returnme()()時,“大腦”會報錯。
下面我們可以來解釋一下腳本2和腳本3的運行詳情,之前說過,裝飾器的工作原理就是腳本1代碼所演 示的那樣。
@decorator
def target():
...
等同于
def decorator(target)():
...
注:python語法中以上寫法是非法的,以上只是為了便于理解。
當你調用被裝飾方法target時,其實首先被執行的是作為裝飾器的decorator函數,然后“大腦 ”會把target方法作為參數傳進去,于是:
#腳本2
def decorator(func):
func()
print('this is decorator')
@decorator
def target():
print('this is target')
target
-------------------------------------------
實際運行情況:
首先調用decorator方法:decorator()
因為decorator方法含1個參數,因此將target傳入:decorator(target)
運行代碼“func()”,根據傳入的參數,實際執行target(),結果打印出:this is target
運行代碼"print('this is decorator')",結果打印出:this is decorator
對比腳本3的運行情況:
#腳本3
def decorator(func):
func()
print('this is decorator')
@decorator
def target():
print('this is target')
target()
-------------------------------------------
實際運行情況:
首先調用decorator方法:decorator()
因為decorator方法含1個參數,因此將target傳入:decorator(target)
運行代碼“func()”,根據傳入的參數,實際執行target(),結果打印出:this is target
運行代碼"print('this is decorator')",結果打印出:this is decorator
以上與腳本2中運行情況完全相同,接下來便是執行腳本2中target沒有的(),也就是執行調用命令。
由于decorator(target)沒有返回一個可以被調用的對象,因此“大腦”提示錯
誤:'NoneType' object is not callable
如果你還不是很清楚,請看下面的等價關系:
@decorator
def target():
...
等同于
def decorator(target)():
...
因此:
target == decorator(target)
target() == decorator(target)()
所以:
假設有一個變量var=target,在將target賦值給var時,其實是將decorator(target)的調用結果賦值給
var,因為var不具備調用性(not callable),因此執行var()時,編譯器會報錯它是個NoneType對象,
不能調用。
綜上所述,你大概已經能夠明白所謂的裝飾器是怎么一回事,它是怎么工作的。但腳本2和腳本3中的 寫法會帶來一些困惑,這個困惑就是通過我們編寫的decorator裝飾器對target進行裝飾后,將target變 成了一個永遠不能被調用的方法,或者說變成了一個調用就報錯的方法。這跟我們的使用習慣以及對方法 的認識是很不協調的,畢竟我們還是習慣一個方法天生注定可以被調用這種看法。所以為了滿足我們對方 法的定義,我們最好將作為裝飾器的方法寫成一個可以返回具有被調用能力的對象的方法。
#腳本4
def whatever():
print('this is whatever')
def decorator(func):
func()
print('this is decorator')
return whatever #1
@decorator
def target():
print('this is target')
------------------------------
輸入:target
結果:
this is target
this is decorator
輸入:target()
結果:
this is target
this is decorator
this is whatever
在#1的位置,你可以return任何可以被調用的方法或類,甚至你可以直接寫成:
def whatever():
print('this is whatever')
def decorator(func):
return whatever
總結
以上是生活随笔為你收集整理的python装饰器副作用_对Python 装饰器的理解心得的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python分类预测降低准确率_pyth
- 下一篇: python博弈论代码_使用 40 多行