Python-20-內嵌函式和閉包
1.內嵌函式和閉包
global關鍵字:把變數變為全域性變數
count=5
>>> def MyFun():
global countcount=10
print(count)
>>> print(count)
10
2.內嵌函式(在函式內部定義一個函式)內部函式的作用域都在外部函式之內,出了fun1就不能呼叫fun2了
>>> def fun1():
print('fun(1)正在被呼叫。。。')
def fun2():
print('fun2正在被呼叫。。。')
fun2()
>>> fun1()
fun(1)正在被呼叫。。。
fun2正在被呼叫。。。
3.閉包
在一個內部函式裡,Funy(y)在它外部的作用域引用到了外部的變數x就稱Funy()是Funx()的閉包
在內部函式中只能對外部函式的變數進行訪問,不能修該
>>> def Fun1():
x=5
def Fun2():
X*=X
return x
return Fun2()
>>> Fun1()
Traceback (most recent call last):
File "<pyshell#55>", line 1, in <module>
Fun1()
File "<pyshell#54>", line 6, in Fun1
return Fun2()
File "<pyshell#54>", line 4, in Fun2
X*=X
UnboundLocalError: local variable 'X' referenced before assignment
.利用容器
>>> def Fun1():
x=[5]def Fun2():
x[0]*=x[0]
return x[0]
return Fun2()
>>> Fun1()
25
4.nonlocal可以用它把內部變數重新定義一下不是區域性變數
>>> def Fun1():
x=[5]
def Fun2():
nonlocal x
x[0]*=x[0]
return x[0]
return Fun2()
>>> Fun1()
25
課後練習:
如果希望在函式中修改全域性變數的值,應該使用什麼關鍵字?
答:global
在巢狀的函式中,如果希望在內部函式修改外部函式的區域性變數,應該使用什麼關鍵字?
答: nonlocal
Python的函式可以巢狀,但要注意訪問的作用域問題哦,請問以下程式碼存在什麼問題呢?
def outside():
print('I am outside!')
def inside():
print('I am inside!')
inside()
答:inside()是內部函式,不能在外部呼叫
使用巢狀函式要注意一點就是作用域問題,inside()函式是內嵌在outside()函式中的,所以inside()是人妻,除了身為老公的outside()可以碰(呼叫),在外邊或者別的函式體裡是無法對其進行呼叫的。
請問為什麼程式碼A沒有報錯,但程式碼B卻報錯了?應該如何修改?
def outside():
var = 5
def inside():
var = 3
print(var)
inside()
outside()
def outside():
var = 5
def inside():
print(var)
var = 3
inside()
outside()
答:這裡outside()函式裡有一個var變數,但要注意的是,內嵌函式inside()也有一個同名的變數,Python為了保護變數的作用域,故將outside()的var變數遮蔽起來,因此此時是無法訪問到外層的var變數的。
應該修改為:
def outside():
var = 5
def inside():
nonlocal var
print(var)
var = 8
inside()
outside()
請問如何訪問funIn()呢?
def funOut():
def funIn():
print('賓果!你成功訪問到我啦!')
return funIn()
以下是“閉包”的一個例子,請你目測下會列印什麼內容?
def funX():
x = 5
def funY():
nonlocal x
x += 1
return x
return funY
a = funX()
print(a())
print(a())
print(a())
答:6
7
8
論壇的解釋:
有些魚油可能會比較疑惑,這……怎麼跟全域性變數一樣了?區域性變數x不是應該在每次呼叫的時候都重新初始化了嗎?!
其實大家仔細看看就明白了,當a = funX()的時候,只要a變數沒有被重新賦值,funX()就沒有被釋放,也就是說區域性變數x就沒有被重新初始化。
所以當全域性變數不適用的時候,可以考慮使用閉包更穩定和安全,你還可以參考 -> 遊戲中的角色移動:閉包在實際開發中的作用