閉包 Closure 和匿名函式

2021-07-02 19:00:44 字數 2781 閱讀 9795

閉包是由函式與其相關的引用環境組合而成的實體.通俗來講就是:在乙個內部函式裡,對在外部作用域(但不是全域性作用域)的變數進行引用,那麼內部函式就被認為是閉包(closure). 看個例子:

>>> 

deffuna

(x):

...

deffunb

(y):

return x + y

...

return funb

...

>>> funa

0x7fdfad04c5f0>

>>> funa(10)

0x7fdfad04c668>

>>> funa(10) == funa(10)

false

>>> funa(10)

0x7fdfad04c7d0>

>>> funa(10)

0x7fdfad04c6e0>

#每次執行都會返回乙個新函式所以記憶體位址會不一樣

>>> i = funa(10)

>>> i

0x7fdfad04c6e0>

>>> i(9)

19

它有這樣的特性:

- 函式是一類值(first-class value),即函式可以作為另乙個函式的返回值或引數,還可以作為乙個變數值.

- 函式可以巢狀定義,即在乙個函式內部可以定義另乙個函式

- 巢狀的函式可以訪問其父作用域中的資料

理解閉包必須知道python的作用域規則:

可以用legb來總結python的作用域規則:當乙個變數被訪問的時候,python會按legb順序來搜尋變數:

注意

訪問規則只對普通變數有效,訪問物件的屬性與此無關.

此規則有乙個重要的限制:

乙個不在區域性作用域裡的變數預設是唯讀的,如果試圖為其繫結乙個新的值,python會認為是在當前區域性作用域裡建立乙個新的變數.

>>> def count():

... fs =

...for i in range(1,4):

... def f():

...return i*i

...return fs

...

>>> f1,f2,f3 = count()

>>> f1()

9>>> f2()

9>>> f3()

9

可能有人認為這段**執行的結果是1,4,9,但是實際結果是9,9,9.這是因為當函式f被加入fslist的時候還沒有執行,只是將函式裝進了list裡面.當函式count函式被呼叫後才開始執行,去尋找i的值是多少,這時候for迴圈結束後得到的i是3所以上述**的結果都為9.有點難理解來翠花上個例子~

>>> for i in range (1,4):

... print i

...123

#for迴圈結束,但是i不會被銷毀,它被最後for迴圈最後的遍歷出的結果`3`賦值.

>>> def count():

... fs =

...for i in range(1,4):

... def f(x=i): return x*x

...return fs

...

>>> y1,y2,y3 = count()

>>> y1()

1>>> y2()

4>>> y3()

9>>> def count():

... fs =

...for i in range(1,4):

... def f(x=i): return x*x, i

...return fs

...

>>> y1,y2,y3 = count()

>>> y3()

(9, 3)

>>> y2()

(4, 3)

>>> y1()

(1, 3) #i返回的結果都為3,但是x是變化的,x在每次迴圈的時候被賦值,然後輸出結果.

定義

有時候我們不需要函式名,直接傳入匿名函式更方便.

關鍵字lambad表示匿名函式,冒號:前面的是引數,後面的是表示式.表示式將計算結果傳給引數.

比如:

>>> map(lambda x: x*x, range(10))

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

#等價於

>>> def f(x):

...return x*x

...

>>> map(f, range(10))

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

是不是感覺方便很多~

怎麼呼叫匿名函式呢?

既然是函式就可以被當作乙個物件賦值給乙個變數,我們可以這樣做:

>>> i = lambda x: x*x 

>>> i(8)

64

匿名函式和閉包

匿名函式 匿名函式和普通函式 function box alert box 閉包概念 閉包是指有權訪問另乙個函式作用域中的變數的函式,建立閉包的常見的方式,就是在乙個函式內部建立另乙個函式,通過另乙個函式訪問這個函式的區域性變數。閉包作用 使用閉包有乙個優點,也是其缺點。可以把區域性變數駐留在記憶體...

閉包和匿名函式

匿名函式 沒有函式名稱的函式 這就是匿名函式 function argument1,argument2 閉包 乙個可以使用另外乙個函式作用域中的變數的函式。如下面的 函式b就是閉包,但是這個前提是 當函式a的內部函式b被函式a外的乙個變數引用的時候,就建立了乙個我們通常所謂的 閉包 意思是說b要變成...

閉包和匿名函式

閉包是指在建立時封裝周圍狀態的函式.即便閉包所在的環境不存在了,閉包中封裝的狀態依然存在.匿名函式其實就是沒有名字的函式 從理論上講閉包和匿名函式是不同的概念.但是php將其視作為相同的概念 注意 閉包和匿名函式其實是偽裝成函式的物件.如果審查php閉包或匿名函式,會發現它們是closure類的例項...