Python - 閉包



什麼是閉包?

Python 閉包是一個巢狀函式,它可以訪問來自封閉函式的變數,而封閉函式已經完成了執行。此類變數未繫結在區域性作用域中。要使用不可變變數(數字或字串),我們必須使用 nonlocal 關鍵字。

Python 閉包的主要優勢在於,它可以幫助避免使用全域性值並提供某種形式的資料隱藏。它們用於 Python 裝飾器。

閉包與巢狀函式密切相關,並允許內部函式捕獲並保留封閉函式的區域性狀態,即使外部函式已完成執行或作用域不再可用。理解閉包需要熟悉巢狀函式、變數作用域以及 Python 如何處理函式物件。

  • 巢狀函式:在 Python 中,函式可以在其他函式內部定義。這些稱為巢狀函式或內部函式。
  • 訪問封閉作用域:內部函式可以訪問封閉(即外部)作用域中的變數。這就是閉包發揮作用的地方。
  • 狀態保留:當內部函式(即閉包)捕獲並保留來自其封閉作用域的變數時,即使外部函式已完成執行或作用域不再可用。

巢狀函式

Python 中的巢狀函式是指在一個函式內部定義另一個函式的做法。這個概念允許我們更有效地組織程式碼、封裝功能和管理變數作用域。

以下是巢狀函式的示例,其中函式B在函式A內部定義。然後從外部函式的作用域內部呼叫內部函式。

示例

def functionA():
   print ("Outer function")
   def functionB():
      print ("Inner function")
   functionB()

functionA()

輸出

Outer function
Inner function

如果外部函式接收任何引數,則可以將其傳遞給內部函式,如下例所示。

def functionA(name):
   print ("Outer function")
   def functionB():
      print ("Inner function")
      print ("Hi {}".format(name))
   functionB()
   
functionA("Python")

輸出

Outer function
Inner function
Hi Python

變數作用域

當建立閉包(即捕獲其封閉作用域中變數的內部函式)時,它會保留對這些變數的訪問許可權,即使外部函式已完成執行。這種行為允許閉包“記住”和操作封閉作用域中變數的值。

示例

以下是對閉包使用變數作用域的示例:

def outer_function(x):
    y = 10
    
    def inner_function(z):
        return x + y + z  # x and y are captured from the enclosing scope
    
    return inner_function

closure = outer_function(5)
result = closure(3)
print(result)  

輸出

18

建立閉包

在 Python 中建立閉包涉及在外部函式中定義一個巢狀函式並返回內部函式。閉包對於捕獲和保留來自封閉作用域的變數狀態很有用。

示例

在下面的示例中,我們有一個 **functionA** 函式,它建立並返回另一個函式 **functionB**。巢狀的 **functionB** 函式是閉包。

外部 **functionA** 函式返回一個 **functionB** 函式並將其分配給 myfunction 變數。即使它已經完成了執行。但是,printer 閉包仍然可以訪問 name 變數。

以下是使用 Python 建立閉包的示例:

def functionA(name):
   name ="New name"
   def functionB():
      print (name)
   return functionB
   
myfunction = functionA("My name")
myfunction()

輸出

New name

nonlocal 關鍵字

在 Python 中,nonlocal 關鍵字允許訪問區域性作用域之外的變數。這用於閉包修改存在於外部變數作用域中的不可變變數。以下是帶有 nonlocal 關鍵字的閉包示例。

def functionA():
   counter =0
   def functionB():
      nonlocal counter
      counter+=1
      return counter
   return functionB

myfunction = functionA()

retval = myfunction()
print ("Counter:", retval)

retval = myfunction()
print ("Counter:", retval)

retval = myfunction()
print ("Counter:", retval)

輸出

Counter: 1
Counter: 2
Counter: 3
廣告