題主你好,
建網(wǎng)站原本是網(wǎng)站策劃師、網(wǎng)絡(luò)程序員、網(wǎng)頁設(shè)計(jì)師等,應(yīng)用各種網(wǎng)絡(luò)程序開發(fā)技術(shù)和網(wǎng)頁設(shè)計(jì)技術(shù)配合操作的協(xié)同工作。成都創(chuàng)新互聯(lián)公司專業(yè)提供網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站,網(wǎng)頁設(shè)計(jì),網(wǎng)站制作(企業(yè)站、成都響應(yīng)式網(wǎng)站建設(shè)公司、電商門戶網(wǎng)站)等服務(wù),從網(wǎng)站深度策劃、搜索引擎友好度優(yōu)化到用戶體驗(yàn)的提升,我們力求做到極致!
關(guān)鍵點(diǎn)在于函數(shù)如果沒有明確使用return關(guān)鍵字指定函數(shù)的返回值,則默認(rèn)返回值是none.
-----
所以temp = hello()這句的理解就是: 執(zhí)行hello()這個(gè)函數(shù), 并且把函數(shù)的返回值賦給變量temp, 但hello()函數(shù)中沒有return語句, 所以hello()函數(shù)的返回值為默認(rèn)的none.
-----
題主還可以在hello()函數(shù)最后加一個(gè): return 123
然后再行一下看看,就明白了.
=====
希望可以幫到題主, 歡迎追問.
不是簡單地返回函數(shù)。至少在Python里,def定義的函數(shù)和lambda定義的函數(shù),后者是包含closure的。
(1)unpack tuple和list, 可以讓函數(shù)返回多個(gè)值
def count():
return (1, 2, 3) # 或者 return [1, 2, 3]
# 把列表解包,把1 2 3 分別賦值給 a b c
a, b, c = count()
print a, b, c
# 輸出 1, 2, 3
(2)假設(shè)你知道Python的dict類型。Python中,在函數(shù)中定義一個(gè)變量的時(shí)候,會在一個(gè)隱藏的叫l(wèi)ocals的dict里面插入key-value,其中key是變量名,value是變量值。而引用一個(gè)變量的時(shí)候,則首先會在這個(gè)叫l(wèi)ocals的dict里面,根據(jù)變量名作為key,去查對應(yīng)的值。
var = 1 # 你可以認(rèn)為這里進(jìn)行了 locals['var'] = 1 的操作
print var # 在對var變量進(jìn)行求值的時(shí)候,就在locals['var']里面找var變量對應(yīng)的值
(3)for循環(huán)中,每次循環(huán)只是給 `i` 重新綁定值
for i in (1, 2, 3):
print i
print i
# 一次輸入 1 2 3 3
每次`for i in (1, 2, 3)`相當(dāng)于在`print i`之前,進(jìn)行了
`locals['i'] = 1`
`locals['i'] = 2`
`locals['i'] = 3`
的操作
所以最后的`print i`再去locals字典里面找`i`的時(shí)候,就變成 3 了。
(4)閉包是 一個(gè)函數(shù)加上這個(gè)函數(shù)引用的外部變量
var = 1
def f():
print var
# 這里的閉包是函數(shù) f 和 f 引用的外部變量 var
def count():
var2 = 2
def f():
print var2
# 這里的閉包是函數(shù) f 和 f 引用的外部變量 var2
return f
拿第一個(gè)函數(shù) f 來說。在 f 運(yùn)行的時(shí)候,解釋器拿著'var'這個(gè)字符串去locals字典里面找,發(fā)現(xiàn)找不到,于是在closure字典里面找,最后closure字典里面找,你可以認(rèn)為就是找closure['var'],然后發(fā)現(xiàn)找到對應(yīng)的值。count里面的 f 函數(shù)同理。
(為了容易理解,我這里說謊了。實(shí)際上 f 壓根沒有closure,count里面的 f 才有。其實(shí)closure壓根不是像locals那樣的字典)
(5)函數(shù)定義時(shí),函數(shù)只是記錄變量的名字。
要區(qū)分什么是名字,什么是值。
`i = 1`這里 i 只是名字,只是一個(gè)字符串 'i' 。這句話運(yùn)行完,locals['i'] = 1,就說 i 對應(yīng)的值是1
def count():
fs = []
for i in range(1, 4):
# 定義一個(gè)函數(shù),等價(jià)于運(yùn)行了 locals['f'] = 真正生成的函數(shù)
# 每次循環(huán),這里都會重新生成一個(gè)函數(shù),然后把重新生成的函數(shù)賦值給 locals['f']
def f():
return i * i # 引用了'i'這個(gè)名字,但并不是引用了'i'對應(yīng)的值
# 等價(jià)于 locals['fs'].append(locals['f'])
# f 不是函數(shù),它只是一個(gè)名字'f'。f 引用的東西,也就是locals['f']才是真正的函數(shù)
fs.append(f)
# 于是這個(gè)for循環(huán)生成了三個(gè)函數(shù),這三個(gè)函數(shù)是沒有名字的,這個(gè)函數(shù)運(yùn)行完后,它們跟'f'這個(gè)名字就毛關(guān)系都沒有了(是的我說慌了,但可以先不管)
# 把整個(gè)列表返回,這個(gè)列表包含了三個(gè)函數(shù)
return fs
# count()返回三個(gè)函數(shù)的列表,unpack 列表的語法把列表中的三個(gè)函數(shù)抽出來,重新給他們命名為 f1, f2, f3
# 也就是說,
# locals['f1'] = 列表中的第1個(gè)函數(shù)
# locals['f2'] = 列表中的第2個(gè)函數(shù)
# locals['f3'] = 列表中的第3個(gè)函數(shù)
# 這三個(gè)函數(shù)跟'f'這個(gè)名字現(xiàn)在毛關(guān)系都沒有。(其實(shí)是有的,但為了說明需要簡化,現(xiàn)在你可以完全不管括號里面說的話)
f1, f2, f3 = count()
print f1(), f2(), f3()
# 好了我們運(yùn)行它們,輸入都是 9
# def f():
# return i * i
這是因?yàn)?f1 現(xiàn)在對應(yīng)的函數(shù),里面引用了 'i' 這個(gè)字符串,我們根據(jù) 'i '這個(gè)字符串去找它對應(yīng)的值,先找到 f 當(dāng)前的locals字典,發(fā)現(xiàn)沒有,因?yàn)楹瘮?shù)定義的時(shí)候沒有定義 i 變量。然后再去closure['i']里面找,因?yàn)镻ython是通過closure字典實(shí)現(xiàn)閉包的(就當(dāng)它是對的好不好),所以我們可以在closure['i']找到值,這個(gè)值就是我們上一次運(yùn)行的時(shí)候count函數(shù)里面殘留的locals['i'],而由于for循環(huán)三遍之后,locals['i'] == 3,所以找到 i 的值就是3。所以最后輸出都是9