python 閉包 1.什麼是閉包 如果在一個內部函數里,對在外部作用域(但不是在全局作用域)的變數進行引用, 那麼[內部函數和該變數]就構成了閉包(closure)。 inner 和 x構成一個閉包 2.閉包使用中的坑 閉包中不能直接修改外部函數的局部變數 (如果使用類似 修改x的值,會直接報錯 ...
# python 閉包 #
1.什麼是閉包
如果在一個內部函數里,對在外部作用域(但不是在全局作用域)的變數進行引用,
那麼[內部函數和該變數]就構成了閉包(closure)。
def out(x):
def inner():
print(x)
return inner
inner 和 x構成一個閉包
2.閉包使用中的坑
閉包中不能直接修改外部函數的局部變數
(如果使用類似x = x + 1
修改x的值,會直接報錯UnboundLocalError
原因是企圖修改x
會讓函數認為x
是局部變數,在執行=
右邊的x + 1
時找不到變數x
)
def out():
x = 0
def inner():
x = 1
print(x)
print(x) # 顯示改變前變數的值
inner() # 執行inner函數
print(x) # 顯示改變後的變數值
return inner
輸出0 1 0
如果非要修改外部函數局部變數的值
需要使用nonlocal
def out():
x = 0
def inner():
nonlocal x
x = 1
print(x)
print(x) # 顯示改變前變數的值
inner() # 執行inner函數
print(x) # 顯示改變後的變數值
return inner
輸出0 1 1
當閉包中引用了迴圈變數時
def out():
fs = []
for i in range(1, 4):
i = i
def inner(x):
return i + x
fs.append(inner)
return fs
f1, f2, f3 = out()
print(f1(1))
print(f2(1))
print(f3(1))
輸出4 4 4
而不是2 3 4
閉包中的函數在被調用時才執行,
當調用inner
時外層函數out
已經執行完了,
但是變數i
不會銷毀,因為函數inner
需要使用變數i
,
而此時變數i
的值為3,所以輸出4 4 4
想要獲得2 3 4
,需要在每一次迴圈時都記錄變數i
的值
def out():
fs = []
for i in range(1, 4):
i = i
def inner(x, y=i):
return x + y
fs.append(inner)
return fs
f1, f2, f3 = out()
print(f1(1))
print(f2(1))
print(f3(1))
輸出2 3 4