這一次徹底搞清楚閉包函式

2021-09-19 10:52:07 字數 2635 閱讀 9592

閉包(closure)是函式式程式設計的重要的語法結構。

函式式程式設計是一種程式設計正規化 (而面向過程程式設計和物件導向程式設計也都是程式設計正規化)。

在面向過程程式設計中,我們見到過函式(function);在物件導向程式設計中,我們見過物件(object)。

函式和物件的根本目的是以某種邏輯方式組織**,並提高**的可重複使用性(reusability)。

閉包也是一種組織**的結構,它同樣提高了**的可重複使用性。

不同的語言實現閉包的方式不同。

python以函式物件為基礎,為閉包這一語法結構提供支援的 (我們在特殊方法與多正規化中,已經多次看到python使用物件來實現一些特殊的語法)。

python一切皆物件,函式這一語法結構也是乙個物件

在函式物件中,我們像使用乙個普通物件一樣使用函式物件,比如更改函式物件的名字,或者將函式物件作為引數進行傳遞。

在搞清楚乙個事物的原理,必須先知道相關的概念和定義,關於閉包函式的概念,我從維基百科上找了段相關的定義

在電腦科學中,閉包(closure)是詞法閉包(lexical closure)的簡稱,是引用了自由變數的函式。這個被引用的自由變數將和這個函式一同存在,即使已經離開了創造它的環境也不例外。所以,有另一種說法認為閉包是由函式和與其相關的引用環境組合而成的實體。閉包在執行時可以有多個例項,不同的引用環境和相同的函式組合可以產生不同的例項。

維基百科這段話說的雲裡霧裡的,看完後有點讓人思考人生的感覺。對於閉包的概念我想用一句話解釋清楚

閉包函式其實是定義在內部函式並且包含對外部作用域而非全域性作用域的**引用

還是很難理解,還是來一段**看看吧

def

mybook()

:  book =

"this is my book"

definnerfunc()

:print

(book)

# 閉包

innerfunc(

)mybook(

)

這裡面呼叫mybook的時候就產生了乙個閉包——innerfunc,並且該閉包持有自由變數——book,因此這也意味著,當函式mybook的生期結束之後,book這個變數依然存在,因為它被閉包引用,所以不會被記憶體**。

閉包並不是python中特有的概念,所有程式語言的函式均有閉包的概念。

在為學習閉包之前,我們都是通過引數將外部的值傳給函式,而閉包提供了另外一種思路,包起來,嗯真的很不錯哦。

通過第一部分介紹,不知道你有沒有感覺這個東西和類有點相似,相似點在於他們都提供了對資料的封裝。不同的是閉包本身就是個方法。和類一樣,我們在程式設計時經常會把通用的東西抽象成類,以復用**通用的功能。閉包也是一樣,當我們需要函式粒度的抽象時,閉包就是乙個很好的選擇。

我們在外界可以訪問內部函式. 那這個時候內部函式訪問外部就不⼀定。

因為在外部, 我可以選擇在任意的時間去訪問內部函式。

如果⼀個函式執⾏完畢. 則這個函式中的變數以及區域性命名空間中的內容都將會被銷毀。

在閉包中,如果變數被銷毀了那內部函式將不能正常執⾏。

所以,python規定如果你在內部函式中訪問了外層函式中的變數,那麼這個變數將不會消亡,將會常駐在記憶體中。

也就是說使⽤閉包, 可以保證外層函式中的變數在記憶體中常駐,提供後面的函式使用。

也就是說:

返回的函式物件,不僅僅是乙個函式物件,在該函式外還包裹了一層作用域,這使得,該函式無論在何處呼叫,優先使用自己外層包裹的作用域

def

decorator_func

(func)

:def

(*args,

**kwargs)

:return func(

*args,

**kwargs)

@decorator_func

deffunc

(name)

:print

'my name is'

, name

# 等價於

#decorator_func(func)

rest = func(

'coco'

)print

(rest)

第二個場景 ,就是基於閉包的乙個特性——「惰性求值」。這個應用非常常見,比如目前應用非常多的爬蟲的案例。

import requests

defhtml()

: content = requests.get(

"").read(

)def

get_content()

:return content

return get_content

all= html(

)# 後⾯需要⽤到這⾥⾯的內容就不需要在執⾏⾮常耗時的⽹絡連線操作了

content =

all(

)# 獲取內容

print

(content)

content2 =

all(

)# 重新獲取內容

print

(content2)

一次搞清楚ajax和axios fetch的區別

前端請求基於ajax的時代已逐漸成為將要成為歷史了,es6的fetch和node的axios將會逐漸代替它,本篇博文將就這三者的區別做以比較方便對後兩者的理解和使用。ajax ajax error function axios axios 是乙個基於 promise 的 http 庫,可以用在瀏覽器...

這一次,徹底讀懂Mysql執行計畫

本文主要介紹mysql執行計畫各個欄位的作用,以及如何利用mysql執行計畫優化我們的sql,本文主要面向後端開發程式設計師,以及需要和資料庫打交道的同學們。所謂的執行計畫就是mysql如何執行一條sql語句,包括sql查詢的順序 是否使用索引 以及使用的索引資訊等內容。乙個例子 基本語法 expl...

一次搞清楚移動端適配這幾個坑爹的單位慨念

目錄 移動端適配本身不難,但是因為涉及到單位轉換,想要解釋清楚移動端適配方案,你必須要搞清楚各個單位的慨念。但是由於中英翻譯的問題,我發現很多文章在講解移動端適配時,關於單位,我們有一萬種翻譯方法.物理畫素 邏輯畫素 物理解析度 邏輯解析度 實際畫素 css畫素 裝置畫素 ppi pt dpr。真的...