即函式的返回值可以為乙個函式
// 乙個例子
def outer()
:#外函式
t =[0]
def inner()
:#內函式
t[0]
+=1return t[0]
return inner #外函式返回內函式的引用;
實現機制:
外函式中定義了內函式,內函式運用了外函式的臨時變數(外函式繫結給內函式的區域性變數/閉包變數),外函式返回內函式的引用,這樣便構成了乙個閉包。
閉包兩個重要的知識點:
方法有以下幾種:
臨時變數採用可變物件,如list,上面所舉的例子即為將臨時變數設定為可變物件的情況;
t =[0
]
用關鍵字nonlocal宣告臨時物件:
nonlocal xx
nonlocal 會使得所列出的名稱指向之前在最近的包含作用域中繫結的除全域性變數以外的變數——nonlocal 會使得其所列出的名稱xx不是區域性變數空間的變數,需要向上一層變數空間找這個變數.
如下例:
def outer()
:#外函式
t =0
def inner()
:#內函式
nonlocal t #需要宣告的t在外函式中為臨時變數
t +=
1return t
return inner #外函式返回內函式的引用
如果**中沒有 nonlocal t,會報錯:
unboundlocalerror:local variable 't' referenced before assignment
(區域性變數錯誤:賦值前引用區域性變數t)
我們的原意是要引用外部變數(即在外函式中定義並賦值的t),但是由於內函式中t += 1語句的存在,這種情況下編譯器/直譯器會將t視為乙個區域性變數;
小結:當對作用域中的變數進行賦值時,該變數將成為該作用域的區域性變數,並在外部作用域中隱藏任何類似命名的變數。使用 nonlocal對其進行宣告之後,向上一層變數空間找這個變數。
再舉乙個栗子
def outer
(x):
def inner
(y):
nonlocal x #需要宣告的x在外函式中為輸入引數
x+=y
return x
return inner
這個例子中,呼叫函式時如果寫成:
demo=
outer
(x)print
(demo()
)
則會報錯:
typeerror:inner() missing 1 required positional argument: 'y'
需要寫成demo(xx),xx指的是y值
使用閉包的過程中,一旦外函式被呼叫一次返回了內函式的引用,雖然每次呼叫內函式,是開啟乙個函式執行,過後消亡,但是閉包變數實際上只有乙份,每次開啟內函式都在使用同乙份閉包變數。這意味著在內函式中若修改了閉包變數,每次呼叫完內函式,閉包變數都會發生變化。
接上例,驗證一下閉包變數隨著內函式多次呼叫的變化
demo=
outer(10
) #即x---10
print
(demo(1
)) #即y---1
print
(demo(10
)) #即y---10
,然而此時x不是10,而是11,即在第一次呼叫demo(1
)後,閉包變數x變為11
print
(demo(10
))
得到的結果為11,21,31
舉個例子:廖雪峰python教程返回函式中的例子
def outer()
: fs =
for i in
range(1
,4):
def inner()
:return i*i
fs.(f)return fs
先提一句:關於第大一條變數的問題,在這個例子中,內函式的定義中不含有關於i值的賦值語句,所以不會報錯unboundlocalerror
看外函式的返回函式fs,它是乙個list,按照函式的迴圈控制,我們知道這個list中包含三個元素,每個元素分別為乙個函式,通過以下語句
f1, f2, f3 =
outer
()
我們將這三個元素賦值給f1, f2, f3。在命令列中輸入f1, f2, f3,得到如下,可以看出三者均為函式
(.f>,
.f>,
.f>)
呼叫f1()、f2()、f3()得到相應的結果
print(f1
())print(f2
())print(f3
())
為什麼得到的是9,9,9而不是1,4,9
這時我們注意到三點:
直觀上,我們會理解依據迴圈控制為當i=1時,return 1 * 1;當i=2時,return 2 * 2……
但實際上返回的內函式並沒有立刻執行,因為只有外函式結束之時才會將閉包變數值繫結給內函式,再次呼叫內函式時才會將閉包變數帶入內函式執行。
所以在此例中,返回的內函式時並沒有把i值帶入表示式 i * i 中,即當i=1時,return i * i ,當i=2時,return i * i……對於內函式inner來說,外部變數i隨著迴圈不斷變化,直到外函式結束時(也就是當i=3時,return i * i 後),外函式將i這個閉包變數繫結給內函式,此時繫結給內函式的i值為3。當呼叫f1()、f2()、f3()時將閉包變數i=3帶入內函式執行。
參考的blog:
python返回函式閉包
注意到返回的函式在其定義內部引用了區域性變數args,所以,當乙個函式返回了乙個函式後,其內部的區域性變數還被新函式引用,所以,閉包用起來簡單,實現起來可不容易。另乙個需要注意的問題是,返回的函式並沒有立刻執行,而是直到呼叫了f 才執行。我們來看乙個例子 def count fs for i in ...
Python中的返回函式與閉包
返回函式,顧名思義,就是高階函式可以把函式作為return值返回。與閉包的關係是 閉包需要以返回函式的形式實現。一.返回函式 比如我們有乙個求和函式 def calc sum num list s 0 for i in num list s i return s calc sum 1,2,3,4 1...
python返回函式 python中返回函式
python的函式不但可以返回int str list dict等資料型別,還可以返回函式!例如,定義乙個函式 f 我們讓它返回乙個函式 g,可以這樣寫 deff print call f 定義函式g defg print call g 返回函式g return g 仔細觀察上面的函式定義,我們在函...