通俗的來說,Python中所謂的命名空間可以理解為一個容器。在這個容器中可以裝許多標識符。不同容器中的同名的標識符是不會相互沖突的。理解python的命名空間需要掌握三條規則:
第一,賦值(包括顯式賦值和隱式賦值)產生標識符,賦值的地點決定標識符所處的命名空間。
第二,函數定義(包括def和lambda)產生新的命名空間。
第三,python搜索一個標識符的順序是"LEGB"。
所謂的"LEGB"是python中四層命名空間的英文名字首字母的縮寫。
最里面的一層是L(local),表示在一個函數定義中,而且在這個函數里面沒有再包含函數的定義。
第二層E(enclosing function),表示在一個函數定義中,但這個函數里面還包含有函數的定義,其實L層和E層只是相對的。
第三層G(global),是指一個模塊的命名空間,也就是說在一個.py文件中定義的標識符,但不在一個函數中。
第四層B(builtin),是指python解釋器啟動時就已經具有的命名空間,之所以叫builtin是因為在python解釋器啟動時會自動載入__builtin__模塊,這個模塊中的list、str等內置函數的就處于B層的命名空間中。
這三條規則通過一個例子來看比較明白。如下面例子所示:
>>> g = int('0x3', 0)>>> def outFunc(): e = 2 g = 10 def inFunc(): l = 1 return g + e return inFunc()>>> outFunc() ===> 12
來詳細看看這段代碼中的標識符。
第1行,適用第一條規則“賦值產生標識符”,因此產生一個標識符g。“賦值的地點決定標識符所處的命名空間”,因為g是沒有在一個函數定義中,因此g處于'G'層命名空間中。這一行中還有一個標識符,那就是int。那么int是在什么地方定義的呢?由于int是內置函數,是在__builtin__模塊中定義的,所以int就處于'B'的層命名空間中。
第2行,適用第一條規則,由于def中包含一個隱性的賦值過程,這一行產生一個標識符outFunc,outFunc并不處于一個函數定義的內部,因此,outFunc處于'G'層命名空間中。此外,這一行還適用第二條規則,產生一個新的命名空間。
第3行,適用第一條規則,產生個標識符e,而且由于這是在一個函數定義內,并且內部還有函數定義,因此e處于'E'層命名空間中。
第4行要注意,適用第一條規則,產生一個標識符g,這個g與e一樣外于'E'層命名空間中。這個g與第一行的g是不同的,因為所處的命名空間不一樣。
第5行,適用第一條規則,產生一個處于'E'層命名空間的標識符inFunc。與第2行一樣,這一行定義函數也產生一個新的命名空間。
第6行,適用第一條規則,產生一個標識符l,由于這個l處于一個函數內部,而且在這個函數內部沒有其他函數的定義,因此l處于'L'層命名空間中。
新聞熱點
疑難解答