目錄:
一、global關鍵字
二、內嵌函式
三、閉包
四、課時20課後習題及答案
********************
一、global關鍵字
********************
全域性變數的作用域是整個模組(整個程式碼段),也就是程式碼段內所有的函式內部都可以訪問到全域性變數。但是要注意一點,在函式內部僅僅去訪問全域性變數就好,不要試圖去修改它。
因為那樣的話,Python會使用遮蔽的方式”保護“全域性變數:一旦函式內部試圖修改全域性變數,Python就會在函式內部自動建立一個名字一模一樣的區域性變數,這樣修改的結果只會修改到區域性變數,而不會影響到全域性變數。看下面的例子:
>>> count=5 >>> def myFun(): count = 10 print(count) >>> myFun() 10 >>> count 5
如果覺得有必要在函式中去修改這個全域性變數,那麼你不妨可以使用global關鍵字來達到目的!修改程式如下:
>>> count=5 >>> def myFun(): global count count = 10 print(count) >>> myFun() 10 >>> count 10
二、內嵌函式
****************
Python函式定義是可以巢狀的,也就是允許在函式的內部建立另外一個函式,這種函式叫做內嵌函式或者內部函式。舉個例子:
>>> def fun1(): print("fun1()正在被呼叫") def fun2(): print("fun2()正在被呼叫") fun2() >>> fun1() fun1()正在被呼叫 fun2()正在被呼叫
值得注意的是:就是內部函式整個作用域都在外部函式之內。
另外需要注意的地方:如果在fun1()外部試圖呼叫內部函式fun2(),就會報錯:
>>> fun2() Traceback (most recent call last): File "<pyshell#45>", line 1, in <module> fun2() NameError: name 'fun2' is not defined
***********
三、閉包
***********
閉包是函式程式設計的一個重要的語法結構,函數語言程式設計是一種程式設計正規化,著名的函數語言程式設計語言就是LISP語言。
Python中閉包從表現形式上定義為:如果在一個內部函式內(funY就是這個內部函式),對外部作用域(但不是在全域性作用域)的變數進行引用(x就是被引用的變數,x在外部作用域funX裡面,但不在全域性作用域裡),那麼內部函式就被認為是閉包。
>>> def funX(x): def funY(y): return x*y return funY >>> i = funX(8) >>> i <function funX.<locals>.funY at 0x0000017296857488> >>> type(i) <class 'function'> >>> type(funX) <class 'function'> >>> funX <function funX at 0x0000017296857598> >>> i(5) 40
也可以直接這樣寫:
>>> funX(8)(5)
40
使用閉包時,需要注意的是:因為閉包的概念就是由內部函式而來的,所以也不能在外部函式以外的地方對內部函式進行呼叫:
>>> funY(5) Traceback (most recent call last): File "<pyshell#58>", line 1, in <module> funY(5) NameError: name 'funY' is not defined
在閉包中,外部函式的區域性變數對應內部函式的區域性變數,實際上就相當於之前講的全域性變數跟區域性變數的關係,在內部函式中,你只能對外部函式的區域性變數進行訪問,但不能進行修改。
>>> def funX(): x = 5 def funY(): x *= x return x return funY >>> funX()() Traceback (most recent call last): File "<pyshell#61>", line 1, in <module> funX()() File "<pyshell#60>", line 4, in funY x *= x UnboundLocalError: local variable 'x' referenced before assignment
這個錯誤資訊跟之前講解全域性變數的時候基本一樣,Python認為在內部函式的x是區域性變數的時候,外部函式的x就被遮蔽了起來,所以執行x *= x的時候,在右邊根本找不到區域性變數x的值,因此報錯。
在Python3以前並沒有直接的方案進行解決,只能間接的通過容器型別來存放,因為容器型別不是放在棧裡,所以不會被‘遮蔽’掉。
>>> def funX(): x = [5] def funY(): x[0] *= x[0] return x[0] return funY >>> funX()() 25
在Python3裡有了改進。如果希望在內部函式裡可以修改外部函式裡的區域性變數的值,用關鍵字nonlocal。
>>> def funX(): x = 5 def funY(): nonlocal x x *= x return x return funY >>> funX()() 25
擴充套件閱讀-->遊戲中的移動角色:閉包在實際開發中的作用:(地址是:https://fishc.com.cn/thread-42656-1-1.html)
*******************************
四、課時20課後習題及答案
*******************************