一、什麼是Python閉包
Python閉包是一個函數,它返回一個函數對象,並且可以訪問外部函數的變量。通俗點說,閉包就是在一個函數中定義另一個函數,並且內部的函數可以獲取外部函數的局部變量和參數,即使外部函數已經執行完畢。
具體來說,當一個函數嵌套在另一個函數中,並且內部函數引用外部函數的變量時,就形成了一個閉包。外部函數返回內部函數,內部函數可以訪問外部函數的變量,這個內部函數就是閉包。
def outer(x):
def inner(y):
return x + y
return inner
closure = outer(5)
print(closure(3)) # 輸出8
在這個例子中,outer函數返回inner函數,inner函數可以訪問outer函數的變量x,並且在調用closure時,傳遞了參數3,所以最終輸出了8。
二、 Python閉包的作用
Python閉包有以下幾個作用:
1. 保護數據
閉包可以保護外部函數的變量,使得外部函數的變量不會受到外界的干擾。
def outer():
num = 0
def inner():
nonlocal num # 使用非局部變量,讓內部函數訪問外部函數的變量
num += 1
return num
return inner
closure = outer()
print(closure()) # 輸出1
print(closure()) # 輸出2
在這個例子中,內部函數對外部函數的變量進行了修改,但是這個變量不會被其他外界的變量干擾。使用nonlocal關鍵字,讓內部函數訪問外部函數的變量。
2. 延遲計算
閉包可以實現延遲計算,即只有在調用內部函數時才會進行計算。
def outer(x, y):
def inner():
return x + y
return inner
closure = outer(2, 3)
print(closure()) # 輸出5
在這個例子中,返回的閉包函數在調用時才會計算x + y,實現了延遲計算。
3. 實現裝飾器
Python裝飾器就是閉包的一個經典應用,它可以通過定義一個裝飾器函數,來對其他函數進行擴展。
def my_decorator(func):
def wrapper(*args, **kwargs):
print("Before calling the function.")
result = func(*args, **kwargs)
print("After calling the function.")
return result
return wrapper
@my_decorator
def my_function():
print("Hello World!")
my_function()
在這個例子中,定義了一個裝飾器函數my_decorator,這個裝飾器函數接收一個函數作為參數,返回一個閉包函數wrapper,這個閉包函數在執行前後分別輸出了Before calling the function.和After calling the function.。使用@my_decorator來裝飾my_function,相當於把my_function作為參數傳遞給my_decorator函數,最終得到的就是一個新的my_function函數,並且在調用my_function時,會先調用wrapper函數。
三、Python閉包的注意事項
在使用Python閉包時,需要注意以下幾個事項:
1. 避免使用可變對象作為外部函數的變量
在閉包中操作外部函數的變量時,如果使用了可變對象,可能會出現意料之外的結果。
def outer():
nums = [1, 2, 3]
def inner():
nums.pop()
return nums
return inner
closure = outer()
print(closure()) # 輸出[1, 2]
print(closure()) # 輸出[1]
print(closure()) # 輸出[]
在這個例子中,num是一個列表,每次調用inner函數時,都會修改這個列表,並且返回修改後的結果。但是由於列表是一個可變對象,所以每次調用inner函數時,返回的列表都是一樣的,因為它們都是指向同一個列表。所以在使用閉包時,避免使用可變對象作為外部函數的變量。
2. 調用內部函數時,不需要傳遞參數
在調用閉包時,內部函數不需要傳遞參數,因為它已經獲取了外部函數的變量。
def outer(x):
def inner(y):
return x + y
return inner
closure = outer(5)
print(closure(3)) # 輸出8
print(closure()) # 報錯
在這個例子中,因為內部函數已經獲取了外部函數的變量x,所以在調用closure時,只需要傳遞y這個參數。如果只調用inner(),不傳遞參數,就會報錯。
3. 使用nonlocal關鍵字訪問外部函數的變量
在內部函數中,如果想要設置外部函數的變量,必須使用nonlocal關鍵字來聲明這個變量。
def outer():
count = 0
def inner():
nonlocal count # 使用nonlocal關鍵字,讓內部函數訪問外部的count變量
count += 1
return count
return inner
closure = outer()
print(closure()) # 輸出1
print(closure()) # 輸出2
在這個例子中,內部函數inner對外部函數的變量count進行了修改,但是需要使用nonlocal關鍵字來聲明一下這個變量,讓內部函數訪問外部函數的count變量。
原創文章,作者:DMEUI,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/371427.html