今天在廖雪峰網(wǎng)站的python教程中看到了這樣一個(gè)題目:
請(qǐng)編寫一個(gè)decorator,能在函數(shù)調(diào)用的前后打印出'begin call'和'end call'的日志。
然后看到文章下面有人給出了這樣一個(gè)答案:
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()
輸出結(jié)果是這樣的:
begin call f1():
2016-11-8
end call f1():
本人作為編程的初學(xué)者,感覺輸出結(jié)果應(yīng)該是這樣的才對(duì):
begin call f1():
end call f1():
2016-11-8
因?yàn)榘凑沾a的順序,最后才return result,所以result的值應(yīng)該是最后才出現(xiàn)的才對(duì)。
于是我將代碼中 return result 和 print('end call %s()' % func.__name__)順序調(diào)整了一下,變成這個(gè)樣子:
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()
輸出結(jié)果則變成了這個(gè)樣子:
begin call f1():
2016-11-8
沒有后面的 end call f1(): 這一句??!
于是百度之,翻看了好幾個(gè)文章的解釋,最后在知乎上的一位網(wǎng)友的回答讓我有點(diǎn)眉目了:
他的答案是這樣的:
return 語(yǔ)句就是將結(jié)果返回到調(diào)用的地方,并把程序控制權(quán)一起返回。
比如如果其他地方有一句
num = add(a, b)
return 語(yǔ)句就是把 a + b 返回到 = 右邊,并把程序控制權(quán)交給這條賦值語(yǔ)句,執(zhí)行賦值過(guò)程。
根據(jù)我自己的理解就是,一般情況下 return 語(yǔ)句是函數(shù)定義的最后一部分,而 return 語(yǔ)句后的語(yǔ)句是不會(huì)執(zhí)行的,并且退出函數(shù)。當(dāng)然有其他情況,比如這篇文章所說(shuō)的 return 放在 try 語(yǔ)句塊中的情況下,在 if 語(yǔ)句的情況下,等等等等...這里只討論 return? 在這個(gè)代碼中的作用。
首先, result = func() 這個(gè)語(yǔ)句不是簡(jiǎn)單賦值, 這里還有一個(gè)調(diào)用的作用,即 result = func() 的功能是 將定義的 func() 函數(shù)賦值給 result 并且調(diào)用它,所以整個(gè)定義語(yǔ)句是這樣一個(gè)結(jié)構(gòu):
先執(zhí)行這句:
print('begin call %s():' % func.__name__)
然后執(zhí)行這句:
def f1():
print('2016-11-8')
最后執(zhí)行這句:
print('end call %s():' % func.__name__)
而 return result 的意思是 返回 result 的值,并且返回的值出現(xiàn)在 result 調(diào)用的地方。