def
count()
: fs =
for i in
range(1
,4):
deff()
:return i*i
return fs
f1, f2, f3 = count(
)print
(f1(
), f2(
), f3(
))
注意:在定義 f1, f2, f3 的時候,只是呼叫了函式 count() 的外層,並沒有呼叫函式 f() , 所以輸出的結果是
9
99
因此, 返回閉包時牢記一點:返回函式不要引用任何迴圈變數,或者後續會發生變化的變數。
此外,f1, f2, f3 的定義是列表常用的一種方式
a =[1
,2,3
]b, c, d = a
而如果一定要引用迴圈變數怎麼辦?方法是再建立乙個函式,用該函式的引數繫結迴圈變數當前的值,無論該迴圈變數後續如何更改,已繫結到函式引數的值不變:
def
count()
: fs =
for i in
range(1
,4):
deff
(i):
defg()
:return i * i
return g
)return fs
f1, f2, f3 = count(
)print
(f1(
), f2(
), f3(
))
輸出就變成
1
49
利用閉包返回乙個計數器函式,每次呼叫它返回遞增整數:
應該是最先想到的,很直觀的方法
def
createcounter()
:deff(
):i =
0while
true
: i = i +
1yield i
g = f(
)def
counter()
:return
next
(g)return counter
注意一點,g = f()這一步是必不可少的。
def
createcounter()
: i =
0def
counter()
:nonlocal i
i = i +
1return i
return counter
通過nonlocal 標識該變數是上一級函式中的區域性變數,這裡不推薦使用global將i變成全域性變數
i =
0def
createcounter()
:def
counter()
:global i
i = i +
1return i
return counter
countera = createcounter(
)counterb = createcounter(
)
一旦這樣,countera和counterb會使用同乙個i, 導致結果出錯
想到global和nonlocal, 自然會想到列表這類特殊情況:
def
createcounter()
: s=[0
]def
counter()
: s[0]
=s[0]+
1return s[0]
return counter
這裡注意,s是乙個列表,依舊是區域性變數,但在巢狀函式中可以直接修改,列表的情況比較複雜,舉一些例子:
a).
lis =[1
]deff(
):lis =[0
]return lisf()
print
(lis)
這種情況列表不會改變,當然加上global是可以的,輸出為:
[
1]
b).lis =[1
]deff(
):0)
# lis = [0]
return lisf()
print
(lis)
這種情況,列表會改變,輸出為:
[1,
0]
注意,上面兩句話,如果同時執行,且不調換順序的話,是會報錯的,因為程式認為你是在先修改列表lis, 再定義它0)
lis =[0
]
local variable 'lis' referenced before assignment
c). 同樣的道理,引入返回函式的情況
deff(
):lis =[1
]defg(
):lis =[0
]return lis
g()print
(lis)
return g
f = f(
)print
(f()
)
通過執行可以看到,對列表整體進行操作時:
#使用 lis = [0]:[1
][0]
對列表具體元素進行操作時:[1
,0][
1,0,
0]d). 返回列表與返回列表元素不一樣
lis =[1
]deff(
):lis[0]
= lis[0]
+1return lis
print
(f()
,f()
)
[3]
[3]
而如果,返回的是列表的元素,程式記住的就是該元素的值:
lis =[1
]deff(
):lis[0]
= lis[0]
+1return lis[0]
print
(f()
,f()
)
輸出為:
2
3
最後,是練習題的測試:
countera = createcounter(
)print
(countera(
), countera(
), countera(
), countera(
), countera())
# 1 2 3 4 5
counterb = createcounter()if
[counterb(
), counterb(
), counterb(
), counterb()]
==[1,
2,3,
4]:print
('測試通過!'
)else
:print
('測試失敗!'
)
(推薦)
python函式廖雪峰 偏函式
python的functools模組提供了很多有用的功能,其中乙個就是偏函式 partial function 要注意,這裡的偏函式和數學意義上的偏函式不一樣。在介紹函式引數的時候,我們講到,通過設定引數的預設值,可以降低函式呼叫的難度。而偏函式也可以做到這一點。舉例如下 int 函式可以把字串轉換...
python返回函式 python中返回函式
python的函式不但可以返回int str list dict等資料型別,還可以返回函式!例如,定義乙個函式 f 我們讓它返回乙個函式 g,可以這樣寫 deff print call f 定義函式g defg print call g 返回函式g return g 仔細觀察上面的函式定義,我們在函...
關於返回函式
def sum args def he s 0 for i in args s s i return s return he 返回sum函式內部的函式he 和def he 的縮排相同 print sum 1,2,3,4 返回函式 print sum 123,3,3 返回求和的數值 閉包中盡量不要使用...