python函數閉包概念
一、函數
函數是實現特定功能的代碼段的封裝,在需要時可以多次調用函數來實現該功能。
Python如下定義一個函數,我們可以通過任何變量來將此函數進行賦值操作,如下:
def greet():
return "Hello!"
# 將方法賦給變量(無括號,得到方法對象)
greet_func = greet
# 調用存儲在變量中的方法
print(greet_func())
print(type(greet_func)) # 輸出 greet_func 的類型,由于 greet_func 指向的是 greet 函數對象,所以輸出結果為 <class 'function'>
print(type(greet_func())) # 先調用 greet_func 所指向的函數,得到返回值 "Hello!",然后輸出該返回值的類型,結果為 <class 'str'>。
# 有括號,直接調用方法并將結果賦給變量
greet_result = greet()
print(greet_result)
print(type(greet_result)) # 輸出 greet_result 的類型,由于它存儲的是字符串,所以輸出結果為 <class 'str'>
print(type(greet_result())) # 報錯greet_result 存儲的是字符串 "Hello!",而不是函數對象,所以不能像調用函數一樣在它后面加上括號 ()
在 Python 中,函數是一等公民,這意味著函數可以像其他對象(如整數、字符串等)一樣被賦值給變量。這里將 greet 函數對象賦值給了變量 greet_func。此時 greet_func 實際上指向的是 greet 函數本身,而不是函數的返回值;而 greet_result = greet() 是先調用 greet 方法,然后把返回值賦給 greet_result 變量。
二、閉包
2.1 概念
在 Python 中,閉包(Closure)是一種特殊的函數,它由一個函數和該函數所引用的外部作用域中的變量組成。即使外部函數已經執(zhí)行完畢,其局部變量的生命周期也會因閉包的存在而得以延長,閉包可以繼續(xù)訪問這些變量。
簡單來說,閉包允許函數訪問并操作其定義所在的外部作用域中的變量,即使該外部作用域已經結束。
構成閉包需要滿足以下三個條件:
- 存在一個嵌套函數,即在一個函數內部定義另一個函數。
- 嵌套函數引用了外部函數的局部變量。
- 外部函數返回嵌套函數。
2.2 閉包的應用場景
- 數據封裝和隱藏:可以將數據隱藏在閉包內部,只通過閉包提供的接口來訪問和修改數據。
- 實現回調函數:在事件驅動編程中,閉包可以作為回調函數,保存一些上下文信息。
- 實現裝飾器:裝飾器是閉包的一種常見應用,用于在不修改原函數代碼的情況下,為函數添加額外的功能。
2.3 代碼實例
實例 1:簡單計數器閉包
def outer_function():
# 外部函數的局部變量
count = 0
def inner_function():
# 聲明count為外部函數的局部變量, 以便可以修改它
nonlocal count
count = count + 1
return count
return inner_function
# 創(chuàng)建閉包實例
counter = outer_function()
# 多次調用閉包
print(counter()) # 輸出: 1
print(counter()) # 輸出: 2
print(counter()) # 輸出: 3代碼解釋:
outer_function是外部函數,它定義了局部變量count并初始化為 0。inner_function是嵌套在outer_function內部的函數,它引用了外部函數的count變量,并對其進行加 1 操作。nonlocal關鍵字用于告訴 Python,count變量不是當前inner_function的局部變量,而是外部函數的局部變量,這樣才能在內部函數中修改它。outer_function返回了inner_function,形成了閉包。當調用outer_function()時,會返回inner_function的引用并賦值給counter。每次調用counter()時,count變量的值都會在之前的基礎上增加 1,說明count變量的狀態(tài)被閉包保存下來了。

實例 2:帶參數的閉包
def multiplier(factor):
print("++++++", factor)
def multiply_by_factor(number):
print("++++++", number)
return number * factor
return multiply_by_factor
# 創(chuàng)建一個乘以 3 的閉包
triple = multiplier(3)
# 調用 __closure__ 內置方法可以查看到兩個內存地址,結果返回cell就是閉包,None 則不是閉包,可以看出來其實這是一個元組類型,使用[0].cell_contents可以得到閉合數值,也就閉包所需要的環(huán)境變量。
print(triple.__closure__)
# 閉包所需要的環(huán)境變量
print(triple.__closure__[0].cell_contents)
print(triple.__class__)
print(triple(5))代碼解釋:
multiplier是外部函數,它接受一個參數factor。multiply_by_factor是嵌套函數,它接受一個參數number,并返回number乘以factor的結果。multiplier返回multiply_by_factor,形成閉包。調用multiplier(2)會返回一個閉包,該閉包會將傳入的數字乘以 2,將其賦值給double。同理,multiplier(3)返回的閉包會將傳入的數字乘以 3,賦值給triple。
運行結果:

實例 3:閉包用于數據封裝和隱藏
def account(initial_balance):
balance = initial_balance
def deposit(amount):
nonlocal balance
balance = balance + amount
return balance
def withdraw(amount):
nonlocal balance
if amount <= balance:
balance = balance - amount
return balance
else:
print("余額不足")
return balance
def get_balance():
return balance
return deposit, withdraw, get_balance
# 創(chuàng)建賬戶閉包
deposited, withdrawed, get_balanceed = account(1000)
# 存款操作
print(deposited(500)) # 輸出: 1500
# 取款操作
print(withdrawed(200)) # 輸出: 1300
# 查詢余額
print(get_balanceed()) # 輸出: 1300代碼解釋:
account是外部函數,它接受一個初始余額initial_balance并將其賦值給局部變量balance。deposit、withdraw和get_balance是嵌套函數, 它們 都引用了外 部函數balance變量。deposit函數用于存款,withdraw函數用于取款,get_balance函數用于查詢余額。account函數返回這三個嵌套函數,形成閉包。通過調用account(1000)創(chuàng)建了一個賬戶閉包,并將返回的三個函數分別賦值給deposited、withdrawe和get_balanceed??梢酝ㄟ^調用這些函數來進行賬戶的存款、取款和查詢余額操作, 而balance變量被封裝在閉包內部,外部無法直接訪問,實現了數據的封裝和隱藏。
參考文章:
https://zhuanlan.zhihu.com/p/55949749
到此這篇關于python函數閉包概念的文章就介紹到這了,更多相關python函數閉包內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python開發(fā)之身份證驗證庫id_validator驗證身份證號合法性及根據身份證號返回住址年齡等信息
這篇文章主要介紹了Python開發(fā)之身份證驗證庫id_validator驗證身份證號合法性及Python解析身份證號,根據身份證號返回住址年齡等信息,需要的朋友可以參考下2020-03-03

