🚀 作者 :“大資料小禅”
🚀 粉絲福利 :加入小禅的大資料社群
🚀 歡迎小夥伴們 點贊👍、收藏⭐、留言💬
目錄
進階知識點之閉包
在萬物皆對象的Python中,函數是否能作為函數的傳回值進行傳回呢?
為什麼輸出的結果會是64?
closure是内部函數的一個屬性,用來儲存環境變量
高頻面試點之閉包經典問題
看看下面的程式的運作結果
def my_power():
n = 2
def power(x):
return x ** n
return power #直接把這個函數給return回去
p = my_power()
print(p(4))
輸出:
16
def my_power():
n = 2
def power(x):
return x ** n
return power
n = 3
p = my_power() #在調用函數的時候n=2就被引用,不受n=3的影響。
print(p(4))
輸出:
16
n = 2
def my_power():
def power(x):
return x ** n
return power
n = 3 #雖然上面由一個n=2,但是會找到距離最近的一個n=3替換進來。
p = my_power()
print(p(4))
輸出:
64
例1
def my_power():
n = 2
def power(x):
return x ** n
return power
p = my_power()
print(p.__closure__)
結果:(<cell at 0x00000264518F9A38: int object at 0x00007FFA7F617120>,) #int類型
例2
n = 2
def my_power():
def power(x):
return x ** n
return power
n = 3
p = my_power()
print(p.__closure__)
輸出結果 None
通過例1跟例2對比,我們可以知道,例2并不是閉包。注意了:!!!閉包指的是,在傳回一個函數的同時,将這個函數所攜帶的一些環境,比如說環境變量n=2,去進行這個傳回,而類似第二種就不是一個閉包,他傳回的是一個函數。!!
下面的程式是否是閉包?能否正确運作
def my_power():
n = 2
def power(x):
n += 1 #當在閉包裡面的時候,沒有辦法直接修改n=2的值,是以這個程式會報錯
return x ** n
return power
p = my_power()
print(p(3))
def my_power():
n = 2
def power(x):
nonlocal n #表示引用這個函數外面非全局變量,進行使用,這時候就可以修改這個值。
n += 1
return x ** n
return power
p = my_power()
print(p.__closure__)
#列印出來的是(<cell at 0x00000264518F9A38: int object at 0x00007FFA7F617120>,)可以看到這個變量類型被攜帶出來。
print(p(3))
print(p(3))
輸出:
(<cell at 0x000001BD4D1BC738: int object at 0x00007FFEB90B7120>,)
27
81
def my_power():
n = 2
L = []
for i in range(1, 3): #因為這裡産生1,2兩個數字,是以下面會循環兩次,要用f1,f2兩個變量值來接收,不然報錯
def power():
return i ** n #這裡的i值是不可以确定的,在python中如果連傳入的形參都不确定的話,那麼python編譯完會預設記住上面那個for循環的最後一個值,也就是都是2,是以導緻最後面輸出兩個都是4,而不是一個1,一個4.
L.append(power)
return L
f1, f2 = my_power()
print(f1())
print(f2())
print(f1.__closure__[0].cell_contents) #看閉包裡面攜帶的環境變量是多少
print(f2.__closure__[0].cell_contents)
輸出:
4
4
2
2