iT邦幫忙

2024 iThome 鐵人賽

DAY 25
0
Python

初學者的 30 天 Python 復健課程系列 第 25

復健第二十五天:一開始有點難理解的閉包 closure

  • 分享至 

  • xImage
  •  

學習程式語言有時會遇到一些非常難理解的觀念,而閉包與裝飾器絕對算是初學者很難跨過的坎,幸運的是,逃避並不可恥,即便不太清楚其中的運作細節,知道怎麼用就足以解決大部分的問題,不過今天有幸參與鐵人賽,我們可以試著搞懂看看,如果還是不懂,希望一年後還有機會再來搞懂一次(笑)。

(明天才會寫裝飾器)

閉包(Closures)

所謂**閉包(Closure)**指的是「允許內部函式訪問外部函式的變數」,淺白一點地說,在一些狀況下,如果某個函式裡面又有一個函數,而最內層的函式需要一個變數,這時候函式會透過先前記住創建當時的上下程式碼,來找可以使用的變數,即使在它所在的外部函式已經執行完畢後,內部函式依然能夠使用外部函式中的變數。

當一個函式(內部函式)在另一個函式(外部函式)內被定義,並且這個內部函式「捕捉」並保存了外部函式中的變數,這種情況就稱為閉包。

所以內部函式將外部作用域的變數「封閉」在它自己的環境中,這就是為什麼閉包會稱作「閉包」。

上面這串說明可能還是有點複雜,所以我們也透過程式碼來感受一下閉包是什麼?

範例:

def add_ten():
    ten = 10
    def add(num):
        return num + ten
    return add

closure_result = add_ten()
print(closure_result(5))  # 15
print(closure_result(10))  # 20

我們可以發現在上述的程式碼中,在函式 add_ten 裡面,有變數 ten 與函式 add(num),再往更深層看看函式 add(num) 中還有什麼?

add(num) 裡面,可以發現接受一個 num 的參數,並有一個 ten 的變數,此時我們尚不知 ten 變數裡面有什麼。

接著程式碼將變數 closure_result 賦予 add_ten() 返回的值,也就是 add,所以我們可以得知 closure_result 就變成了 add

然後讓我們試著進行 closure_result(5) 的運算,剛剛有說了,closure_result 可以替換成 addclosure_result(5) 也就變成了 add(5),而這會返回 5 + ten,但由於 add(num) 裡面本身沒有 ten 這個變數,所以 Python 因為閉包的特性,會找到外層的 ten = 10,代表 5 + ten 會變成 5 + 10,也就會得到最後的結果 15


上一篇
復健第二十四天:刻意不想面對的高階函式 Higher Order Functions
下一篇
復健第二十六天:可能聽不懂但會用就還好的裝飾器 decorator
系列文
初學者的 30 天 Python 復健課程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言