python函式閉包
阿新 • • 發佈:2021-11-06
閉包函式
在一些語言中,在函式中可以(巢狀)定義另一個函式時,如果內部的函式引用了外部的函式的變數,則可能產生閉包。閉包可以用來在一個函式與一組“私有”變數之間建立關聯關係。在給定函式被多次呼叫的過程中,這些私有變數能夠保持其永續性。——維基百科
閉包函式的條件
- 閉包函式必須有內嵌函式
- 閉包函式必須引用外層函式的變數
- 閉包函式返回內嵌函式的地址(函式名稱)
閉包函式示例
def first(): age = 10 def second(): # 內嵌函式 print(age) # 引用外層函式的變數 return second # 返回內嵌函式的函式名
我們稱上述函式second為一個閉包函式
判斷一個函式是否為閉包
我們可以通過函式名.closure 在函式為閉包時,返回一個cell ,如果不是閉包函式則返回None
def first(): age = 10 def second(): # 內嵌函式 print(age) # 引用外層函式的變數 print(second.__closure__) return second # 返回內嵌函式的函式名 >>> s = first() >>> s() (<cell at 0x0000027BBE7A7318: int object at 0x00007FF9120FFB60>,) 100
def first():
age = 10
def second(): # 內嵌函式
print(10) # 引用外層函式的變數
print(second.__closure__)
return second # 返回內嵌函式的函式名
>>> s = first()
>>> s()
None
10
second不是閉包函式,因為沒有引用外層函式的變數
def first(age): def second(): # 內嵌函式 print(age) # 引用外層函式的變數 print(second.__closure__) return second # 返回內嵌函式的函式名 >>> s = first() >>> s() (<cell at 0x0000016A608D6408: int object at 0x00007FF9120FFB60>,) 100
second是閉包函式,引用了外層函式的引數
閉包函式的作用
開篇說到閉包函式被多次呼叫的過程中,其引用的外層變數能夠保持其永續性,我們以一個例項來理解這一點。
假如有一個名為avg的函式,它的作用是計算不斷增加的系列值的均值;例如,整個歷史中某個商品的平均收盤價。每天都會增加新的價格,因此平均值要考慮目前為止所有的價格。
實現方式一
class Averager():
def __init__(self):
self.series = []
def __call__(self, new_val):
self.series.append(new_val)
total = sum(self.series)
return total / len(self.series)
>>> avg = Averager()
>>> avg(10)
10.0
>>> avg(11)
10.5
>>> avg(12)
11.0
實現方式二
def make_averager():
series = []
def averager(new_value):
series.append(new_value)
total = sum(series)
return total / len(series)
return averager
>>> avg = make_averager()
>>> avg(10)
10.0
>>> avg(11)
10.5
>>> avg(12)
11.0