閉包(closure)是詞法閉包(lexical closure)的簡稱,是引用了自由變數的函式。這個被引用的自由變數將和這個函式一同存在,即使已經離開了創造它的環境也不例外。所以,有另一種說法認為閉包是由函式和與其相關的引用環境組合而成的實體。
下面就是乙個閉包的例子,可以看到inc3這個函式中引用到了外層傳人的變數n,而這個n就是定義中的自由變數,在這裡為3,而我們如果再定義乙個inc2=inc(2),則在inc2中其自由變數為2。
def
inc(n):
definner_func
(x):
return x+n
return inner_func
inc3 = inc(3)
assert inc3(2) == 5
我們可以通過函式的 _closure_ 來檢視其繫結的自由變數。
>>> inc3.__closure__
(0x0000000002e8f468: int object at 0x000000005fe3efb0>,)
在python中所有變數均是引用,而引用再繫結到實際的物件上,那麼定義閉包時繫結的是自由變數,還是其指向的物件呢?我們設計如下**在定義閉包函式後再更改自由變數,讓其指向不同的物件,其執行結果顯示為後面的物件,因此說明定義函式其繫結的是變數而非物件。
def
out(n):
definner
(): print(n)
n =
return inner
out(1)()
其實這正是python中遲繫結的機制,即閉包中變數的值只有在內部函式被呼叫時才會進行查詢。
某些情況下,我們想更改外部的自由變數,在python2中是無法做到的,而在python3中引入了nonlocal關鍵字,可以更改自由變數。
def
out(n):
definner
():nonlocal n
n += 1
print(n)
return inner
x = out(1)
x(), x()
# 結果
# 2# 3
lambda也是同樣的閉包原理,因此在使用lambda時也要注意閉包函式執行時才會查詢實際值,否則可能出現意料外的情況。
def
get_map_funs
(n):
return [lambda x:x**i for i in range(n)]
print([j(2) for j in get_map_funs(6)])
# 結果 [32, 32, 32, 32, 32, 32]
該問題有兩種修改方式:
def
get_map_funs
(n):
return (lambda x:x**i for i in range(n))
print([j(2) for j in get_map_funs(6)])
#結果 [1, 2, 4, 8, 16, 32]
def
get_map_funs
(n):
return [lambda x,i=i:x**i for i in range(n)]
print([j(2) for j in get_map_funs(6)])
#結果 [1, 2, 4, 8, 16, 32]
python 閉包 python 閉包
閉包 因為python中函式也可以當作物件,所以如果出現當我們返回乙個函式,而該函式含有外部變數的時候就形成了閉包。閉包的特點 是個巢狀函式 可以獲得非區域性的變數 將函式當作物件返回 看乙個例子會更易理解 def make printer msg msg hi there def printer ...
Python語言特性 閉包
1.閉包的概述 閉包是指在乙個函式中定義了乙個另外乙個函式,內函式裡運用了外函式的臨時變數,並且外函式的返回值是內函式的引用,這樣就構成了乙個閉包。2.閉包的特點 總結一下,建立乙個閉包必須滿足以下幾點 由於這樣的特點,使用閉包,可以隱藏內部函式的工作細節,只給外部使用者提供乙個可以執行的內部函式的...
python怎麼閉包 Python閉包
python閉包教程 閉包就是乙個 在閉包的記憶功能 在 python 中,獲到閉包中的變數讓閉包本身擁有了記憶效應,閉包中的邏輯可以修改閉包捕獲的變數,變數會跟隨閉包生命期一直存在,閉包本身就如同變數一樣擁有了記憶功能。python閉包定義詳解 語法def func param def func ...