廖雪峰 返回函式 2020 1 3

2021-10-01 21:12:07 字數 4006 閱讀 6298

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 標識該變數是上一級函式中的區域性變數,這裡不推薦使用globali變成全域性變數

i =

0def

createcounter()

:def

counter()

:global i

i = i +

1return i

return counter

countera = createcounter(

)counterb = createcounter(

)

一旦這樣,counteracounterb會使用同乙個i, 導致結果出錯

想到globalnonlocal, 自然會想到列表這類特殊情況:

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 返回求和的數值 閉包中盡量不要使用...