目錄:
一、global關鍵字
二、內嵌函數
三、閉包
四、課時20課后習題及答案
?
********************
一、global關鍵字
********************
全局變量的作用域是整個模塊(整個代碼段),也就是代碼段內所有的函數內部都可以訪問到全局變量。但是要注意一點,在函數內部僅僅去訪問全局變量就好,不要試圖去修改它。
因為那樣的話,Python會使用屏蔽的方式”保護“全局變量:一旦函數內部試圖修改全局變量,Python就會在函數內部自動創建一個名字一模一樣的局部變量,這樣修改的結果只會修改到局部變量,而不會影響到全局變量。看下面的例子:
>>> count=5 >>> def myFun():count = 10print(count)>>> myFun() 10 >>> count 5
如果覺得有必要在函數中去修改這個全局變量,那么你不妨可以使用global關鍵字來達到目的!修改程序如下:
>>> count=5 >>> def myFun():global countcount = 10print(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*yreturn 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 = 5def funY():x *= xreturn xreturn funY>>> funX()() Traceback (most recent call last):File "<pyshell#61>", line 1, in <module>funX()()File "<pyshell#60>", line 4, in funYx *= 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 = 5def funY():nonlocal xx *= xreturn xreturn funY>>> funX()() 25
擴展閱讀-->游戲中的移動角色:閉包在實際開發中的作用:(地址是:https://fishc.com.cn/thread-42656-1-1.html)
?
*******************************
四、課時20課后習題及答案
*******************************
?
?