深入理解python中得閉包

2022-05-05 23:03:09 字數 2820 閱讀 8651

1、什麼事閉包?

閉包的定義有很多種,下面是python官網給出的定義:

閉包是詞法閉包(lexical closure)的簡稱,是引用了自由變數的函式,這個被引用的自由變數將和這個函式一同存在,即使已經離開了創造它的環境也不例外。

所以,有另一種說法認為閉包是由函式和與其相關的引用環境組合而成的實體。

上述定義聽起來似乎有點繞,直白點的定義如下:

閉包就是乙個特殊的內部函式,具體特殊在**呢?就是該內部函式引用了外部作用域的一些變數(注意,外部作用於變數不包含全域性變數),那麼內部函式就被認為是閉包(closure)

2、閉包的本質

簡單說,閉包的本質就是根據不同的配置資訊得到不同的結果

3、閉包的例子

我們知道,人分為成年人跟未成年人,加入給定乙個人的年齡,根據是否是未成年人列印出不同的資訊,可以用如下實現,當然,這個需求可以直接根據用if判斷分支處理,此處只是簡單闡述閉包的用法

def

outer(age):

a ={}

def get_info(name=none, work=none, age=age):

if age < 18:

a['name

'] =name

a['age

'] =age

else

: a[

'name

'] =name

a['age

'] =age

a['work

'] =work

return

a

return

get_info

if__name__ == "

__main__":

p1 = outer(15)

p2 = outer(20)

print p1('

zhangsan

', none)

print p2('

lisi

', '

pythoner

')

先看下執行結果

我們來結合這段簡單的**分析下閉包

外部函式:outer()

內部函式:get_info()

外部作用域有個age

內部函式引用了外部作用域的age變數

分析到這就該確定get_info()是乙個閉包了,因為閉包的定義只需滿足兩條:1、內部函式 2、引用了外部作用域的乙個變數

結合官網給出的定義(函式和與其相關的引用環境而組合成的實體)來分析,函式就是get_info() 引用環境就是age

4、自由變數

按照函式的生命週期分析,在執行完p1=outer(15)之後,返回了乙個函式物件賦值給p1,正常情況下區域性變數age應該銷毀了,但是為什麼再執行p1()的時候還能訪問到age呢?

這涉及到乙個特殊的定義:自由變數, 自由變數的定義很簡單,閉包所引用的外部作用域變數稱為自由變數。

當乙個變數變成自由變數之後,其作用域會發生相應的改變,本文不做具體的闡述,只需知道自由變數隨閉包存活就可以了。 

5、閉包操作自由變數所需要的注意事項

如果自由變數是可變物件(list,map...這裡沒有列出tuple是因為tuple是不可改變物件),那麼閉包可以更新自由變數

如果自由變數是不可變物件(數值,字元竄,tuple...),那麼閉包不可以更新自由變數,看下面兩個例子

(1)自由變數為不可變物件

def

foo():

a = 10

defbar():

a = a + 10

return

a

return

barif

__name__ == "

__main__":

b =foo()

print b()

如果執行這段**,會得到以下結果

(2)自由變數為可變物件

def

foo():

a =defbar():

return

a

return

barif

__name__ == "

__main__":

b =foo()

print b()

執行這段**會輸出:[100]

6、猜想

將上述程式稍作修改,請猜測執行結果

def

foo():

a =defbar():

return

a

return

barif

__name__ == "

__main__":

b =foo()

c =foo()

print

b()

print

b()

print c()

2、自由變數的生命週期等同於閉包的生命週期,也就是說在第二次執行print b()的時候,自由變數是被第一次執行print b()操作之後的。。。

提示到這大家猜也能猜到結果吧!!!!    

Python 深入理解閉包

函式物件是使用def語句定義的,函式物件的作用域與def所在的層級相同。比如下面 我們在line conf函式的隸屬範圍內定義的函式line,就只能在line conf的隸屬範圍內呼叫。def line conf def line x return 2 x 1 print line 5 within...

深入理解閉包

閉包的定義 mdn 對閉包的定義 根據上面的例子,舉乙個例子 var str xiaoqi function getname getname 函式可以返回str這個變數,但str即不是getname函式的區域性變數,也不是foo函式的引數,所以str就是自由變數。這樣函式getname就是乙個閉包。...

深入理解JavaScript閉包

一 什麼是閉包 多個 兩個或兩個以上 函式巢狀,當內部函式被儲存到外部時,將會生成閉包。內部函式在外面執行的時候一定能夠呼叫的了原來它在的那個函式環境裡的變數。閉包會導致原有作用域鏈不釋放,造成記憶體洩露。functiona var aaa 123 return b var glob 100 var...