今天在廖雪峰網站的python教程中看到了這樣一個題目:
請編寫一個decorator,能在函數調用的前后打印出'begin call'和'end call'的日志。
然后看到文章下面有人給出了這樣一個答案:
def log(func):
??? def dec():
??????? print('begin call %s():' % func.__name__)
??????? result = func()
??????? print('end call %s():' % func.__name__)
??????? return result
??? return dec
@log
def f1():
??? print('2016-11-8')
f1()
輸出結果是這樣的:
begin call f1():
2016-11-8
end call f1():
本人作為編程的初學者,感覺輸出結果應該是這樣的才對:
begin call f1():
end call f1():
2016-11-8
因為按照代碼的順序,最后才return result,所以result的值應該是最后才出現的才對。
于是我將代碼中 return result 和 print('end call %s()' % func.__name__)順序調整了一下,變成這個樣子:
def log(func):
??? def dec():
??? print('begin call %s():' % func.__name__)
??? result = func()
??? return result
??? print('end call %s():' % func.__name__)
return dec
@log
def f1():
??? print('2016-11-8')
f1()
輸出結果則變成了這個樣子:
begin call f1():
2016-11-8
沒有后面的 end call f1(): 這一句??!
于是百度之,翻看了好幾個文章的解釋,最后在知乎上的一位網友的回答讓我有點眉目了:
他的答案是這樣的:
return 語句就是將結果返回到調用的地方,并把程序控制權一起返回。
比如如果其他地方有一句
num = add(a, b)
return 語句就是把 a + b 返回到 = 右邊,并把程序控制權交給這條賦值語句,執行賦值過程。
根據我自己的理解就是,一般情況下 return 語句是函數定義的最后一部分,而 return 語句后的語句是不會執行的,并且退出函數。當然有其他情況,比如這篇文章所說的 return 放在 try 語句塊中的情況下,在 if 語句的情況下,等等等等...這里只討論 return? 在這個代碼中的作用。
首先, result = func() 這個語句不是簡單賦值, 這里還有一個調用的作用,即 result = func() 的功能是 將定義的 func() 函數賦值給 result 并且調用它,所以整個定義語句是這樣一個結構:
先執行這句:
print('begin call %s():' % func.__name__)
然后執行這句:
def f1():
print('2016-11-8')
最后執行這句:
print('end call %s():' % func.__name__)
而 return result 的意思是 返回 result 的值,并且返回的值出現在 result 調用的地方。