python高階教程-命名空間與作用域
- 2019 年 11 月 20 日
- 筆記
本篇內容來自原創小冊子《python高階教程》,點擊查看目錄。
問題引入
文件1內容如下:

文件2內容如下:

如果我們運行文件2,結果會是什麼呢?

可以看到,文件2中的from file_one import file_one_var1
語句執行後,文件1中的內容立即全部執行,所以輸出了file one is running
。接着在文件2中輸出了file_one_var1
的值,但是輸出file_one_var2
時報錯。
問題在於,明明文件1中的所有語句都執行過了,為什麼file_one_var2
無法在文件2中使用?這涉及到python的命名空間與作用域問題。
名詞解釋
- 命名空間
命名空間(Namespace):名字(標識符)到對象的映射。
簡而言之,命名空間可以理解為:記錄對象和對象名字對應關係的空間;現今 python 的大部分命名空間是通過字典來實現的, 也即一個命名空間就是名字到對象的映射,標識符是鍵,對象則是值。
- 作用域
作用域(Scope):本質是一塊文本區域, Python 通過該文本區域可以直接訪問相應的命名空間。
直接訪問是指通過名字訪問,如print(a)對a是直接訪問;屬性訪 問指的是通過點號訪問,如print(a.A)對A是屬性訪問。
python的作用域
- 四種作用域

- LEGB法則

- 特殊關鍵字
- global 可以允許修改全局變量
- nonlocal 將變量的命名空間由enclosing引入local
類的命名空間
待增補。
練習

這裡c
是模塊里的全局變量,在bar
函數中試圖對全局變量進行修改,但是執行完bar
函數後打印c
,發現還是global
,修改失敗。可以看到,這裡在global域和local域各有一個對象c
,對全局變量的修改不可行。

這裡使用global
關鍵字聲明了全局變量,修改成功。注意global
關鍵字並沒有把c
引入local域,因為打印locals()
函數發現local域沒有對象。

定義了嵌套函數foo_in()
, 對foo_in()
來說,foo()
的作用域為enclosing。這裡試圖直接在local域使用enclosing域的對象,但是報錯。

使用關鍵詞nonlocal後,可以在local域使用enclosing域的對象,並且nonlocal可以把enclosing域的對象引入local域,因為打印locals()
後發現命名空間里有a
。