一个例子带你搞懂python作用域中的global、nonlocal和local
在編程中,只要接觸過函數的,我相信都理解什么是全局變量和局部變量,概念比較簡單,這里就不做解釋了。在python中,用global語句就能將變量定義為全局變量,但是最近又發現有個nonlocal,一時搞不太清楚,仔細琢磨之后才搞明白。
首先看看官方文檔里面是怎么說的:
global 語句是作用于整個當前代碼塊的聲明。 它意味著所列出的標識符將被解讀為全局變量。
nonlocal語句會使得所列出的名稱指向之前在最近的包含作用域中綁定的除全局變量以外的變量。
注意劃重點了,global就是全局變量,這沒有問題。至于nonlocal,“之前”、”最近“和“除全局變量以外”,就是最核心的地方,接下來用一個例子說明一下。
下面的示例代碼同樣來自官方文檔
def scope_test():def do_local():spam = "local spam"def do_nonlocal():nonlocal spamspam = "nonlocal spam"def do_global():global spamspam = "global spam"spam = "test spam"do_local()print("After local assignment:", spam)do_nonlocal()print("After nonlocal assignment:", spam)do_global()print("After global assignment:", spam)scope_test() print("In global scope:", spam)我們可以看到,這是定義了一個scope_test(),然后它里面又分別定義了三個函數do_local()、do_nonlocal()和do_global()。
輸出的結果是什么呢?感興趣的同學先自己琢磨琢磨,我放一張圖提示一下:
下面正式揭曉答案了,輸出結果為:(高亮忽視掉)
我們觀察四個print函數,首先,do_local()里面的spam是局部變量(local),這是毫無疑問的,所以它是不能改變spam的內容的,調用它之后,因為之前spam="test spam"了,所以輸出為仍然為"After local assignment: test spam"。
然后,do_nonlocal()里面的 spam,因為有nonlocal進行修飾,它的作用范圍,就不是局部了,那是哪里呢?正如文檔中提到的,“指向之前在最近的包含作用域中綁定的除全局變量以外的變量”,在調用do_nonlocal()時,哪個之前的spam離它最近呢?很明顯,是spam="test spam"這一個,所以這個spam就變為了spam = "nonlocal spam",后面輸出自然就是“After nonlocal assignment: nonlocal spam”。
為了加深理解,我們看看如果把spam = "test spam"搬到函數外面會怎么樣。
spam = "test spam"def scope_test():def do_local():spam = "local spam"def do_nonlocal():nonlocal spamspam = "nonlocal spam"def do_global():global spamspam = "global spam"do_local()print("After local assignment:", spam)do_nonlocal()print("After nonlocal assignment:", spam)do_global()print("After global assignment:", spam)scope_test() print("In global scope:", spam)此時會報錯:
File "<ipython-input-1-3e4be319dd22>", line 7nonlocal spam^ SyntaxError: no binding for nonlocal 'spam' found這就充分說明了,nonlocal是不能指向全局變量的。
接著,do_global()里面的spam,很明顯就是全局變量,對它進行賦值spam = "global spam",是對全局變量賦值。那影響print("After global assignment:", spam)嗎?不影響,因為這句print中的spam是最開始spam = "test spam"中的那個,它被do_nonlocal()賦值為“nonlocal spam”,注意它可不是全局變量,因為在函數scope_test()中。所以說,此spam非彼spam,一個是全局變量,另一個雖然相對于小函數來說,是非局部變量,但畢竟也是大函數的局部變量呀,所以第三個print自然為“After global assignment: nonlocal spam”。
那到了最后,就簡單了,因為調用完了函數scope_test(),里面只有do_global()改變了全局變量spam = "global spam",所以自然最后輸出“In global scope: global spam"。
總結來說,全局變量global其實是個絕對概念,一旦使用,就會在整個代碼文件適用;而local和nonlocal,無非是相對概念,就好像我們每個人自己可能都是學生(local),活到老學到老,只不過相對其他人來說,有的人是老師(非學生nonlocal)而已。
希望這篇文章能幫助大家理解。
總結
以上是生活随笔為你收集整理的一个例子带你搞懂python作用域中的global、nonlocal和local的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 支持4G通话的国产平板支持4G的平板
- 下一篇: cad的长图怎么实现完美的拼接cad怎么