Python/作用域與名字空間

維基教科書,自由的教學讀本

變量的作用域共有4種:

  • L (Local) 局部作用域
  • E (Enclosing) 外層非全局的閉包作用域
  • G (Global) 全局作用域
  • B (Built-in) 內建作用域

按照L –> E –> G –>B 的順序查找變量。

Python 中只有模塊(module)、類(class)、函數(def、lambda)才會引入新的作用域,其它的代碼塊(如 if/elif/else/、try/except、for/while等)不會引入新的作用域,這些語句內定義的變量,在語句的外部也可以訪問。

類與函數可以閉包(enclosing)。如果在一個內部函數裡,對一個外部作用域(但不是全局作用域)的變量進行引用,那麼內部函數就被稱為閉包(closure),而這個被內部函數引用的變量則被成為自由變量

global關鍵字指明要訪問全局的變量。nonlocal關鍵字指明要訪問外層非全局作用域的變量。在函數作用域內部,可以讀訪問全局變量,但如果修改則自動被當作是一個同名的局部變量,除非顯式使用global關鍵字。如:

list1 = []
def test3():
   list1 = [2]

nonlocal是從Python 3.0引入的關鍵字,允許賦值修改外層非全局的變量。

從Python解釋器的實現看,維持全局名字字典與局部名字字典,可以分別用globals()與locals()列出兩個作用域內的全部名字。對於類或對象實例,還可以用vars(InstanceName)訪問其類或實例作用域內的名字。注意,locals()的值只能讀不能修改。