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