国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

深入理解Python中命名空間的查找規(guī)則LEGB

2020-01-04 17:59:14
字體:
供稿:網(wǎng)友

這篇文章主要介紹了深入理解Python中命名空間的查找規(guī)則LEGB,作者根據(jù)Python3.x版本進行講解,需要的朋友可以參考下

名字空間

Python 的名字空間是 Python 一個非常核心的內(nèi)容。

其他語言中如 C 中,變量名是內(nèi)存地址的別名,而在 Python 中,名字是一個字符串對象,它與他指向的對象構(gòu)成一個{name:object}關(guān)聯(lián)。

Python 由很多名字空間,而 LEGB 則是名字空間的一種查找規(guī)則。

作用域

Python 中name-object的關(guān)聯(lián)存儲在不同的作用域中,各個不同的作用域是相互獨立的。而我們就在不同的作用域中搜索name-object。

舉個栗子,來說明作用域是相互獨立的。

 

 
  1. In [11]: i = "G" 
  2.  
  3. In [12]: def test(): 
  4. i = "L" 
  5. print i, "in locals" 
  6. ....: 
  7.  
  8. In [13]: test() 
  9. in locals 
  10.  
  11. In [14]: print i, "in globals" 
  12. in globals 

在上面的栗子中,我們定義了兩次 i,在 test 函數(shù)中是 i-L,在外面是 i-G。為什么在 test 函數(shù)中,我們 i 指向的是對象 L,而在外面,i 指向的則是 G?這就是 LEGB 的作用。

簡述

簡而言之,LEGB 代表名字查找順序: locals -> enclosing function -> globals -> __builtins__

locals 是函數(shù)內(nèi)的名字空間,包括局部變量和形參

enclosing 外部嵌套函數(shù)的名字空間(閉包中常見)

globals 全局變量,函數(shù)定義所在模塊的名字空間

builtins 內(nèi)置模塊的名字空間

所以,在 Python 中檢索一個變量的時候,優(yōu)先回到 locals 里面來檢索,檢索不到的情況下會檢索 enclosing ,enclosing 沒有則到 globals 全局變量里面檢索,最后是到 builtins 里面來檢索。

當然,因為 builtins 的特殊性,我們可以直接在 builtins 里面添加變量,這樣就可以在任意模塊中訪問變量,不過這種方法太過于變態(tài),不推薦這么做。

locals,globals

函數(shù)的形參跟內(nèi)部變量都存儲在 locals 中。

 

 
  1. In [1]: def f(x): 
  2. ...: a = x 
  3. ...: print a 
  4. ...: print locals() 
  5. ...: 
  6.  
  7.  
  8. In [2]: f("hello"
  9. hello 
  10. {'a''hello''x''hello'

不過在函數(shù)內(nèi)部調(diào)用global 聲明的時候,可以將變量存儲在 globals 中

 

 
  1. In [6]: def f(x): 
  2. ...: global a 
  3. ...: a = x 
  4. ...: print a 
  5. ...: print locals() 
  6. ...: 
  7.  
  8. In [7]: f("hello"
  9. hello 
  10. {'x''hello'
  11.  
  12. In [8]: print a 
  13. hello 
  14.  
  15. In [9]: print x 
  16. --------------------------------------------------------------------------- 
  17. NameError Traceback (most recent call last) 
  18. <ipython-input-9-2d264e11d975> in <module>() 
  19. ----> 1 print x 
  20.  
  21. NameError: name 'x' is not defined 

如上面栗子中那樣,在函數(shù)中聲明 a 為全局變量,則函數(shù) f 的 locals只有參數(shù) x,而沒有變量,而在外部可以使用變量 a,而使用 x 的時候則是NameError

Enclosed

Enclosing 是外部嵌套函數(shù)的名字空間。我們經(jīng)常在閉包中用到。在 Python3中提供了一個 nonlocal關(guān)鍵字來修改外部嵌套函數(shù)的名字空間,但是要使用 Python3才有,我等使用 Python2的只能眼饞一下。

 

 
  1. In [11]: def outer(): 
  2. ....: a_var = 'enclosed value' 
  3. ....: print a_var 
  4. ....: def inner(): 
  5. ....: a_var = 'local value' 
  6. ....: print(a_var) 
  7. ....: inner() 
  8. ....: print a_var 
  9. ....: 
  10.  
  11. In [12]: outer() 
  12. enclosed value 
  13. local value 
  14. enclosed value 

下面的栗子簡單示范一下 nonlocal 的用法,實在 Python3下面才可以正常運行的:

 

 
  1. In [1]: a_var = 'global value' 
  2.  
  3. In [2]: def outer(): 
  4. ...: a_var = "local value" 
  5. ...: print("outer befor", a_var) 
  6. ...: def inner(): 
  7. ...: nonlocal a_var 
  8. ...: a_var = "inner value" 
  9. ...: print("in inner():", a_var) 
  10. ...: inner() 
  11. ...: print("outer inner:", a_var) 
  12. ...: 
  13.  
  14. In [3]: outer() 
  15. outer befor local value 
  16. in inner(): inner value 
  17. outer inner: inner value 
  18.  
  19. In [4]: print(a_var) 
  20. global value 

builtins

builtins 則是內(nèi)置模塊,輕易不要修改

 

 
  1. In [19]: b 
  2. --------------------------------------------------------------------------- 
  3. NameError Traceback (most recent call last) 
  4. <ipython-input-19-3b5d5c371295> in <module>() 
  5. ----> 1 b 
  6.  
  7. NameError: name 'b' is not defined 
  8.  
  9. In [20]: __builtins__.b = "builtins" 
  10.  
  11. In [21]: b 
  12. Out[21]: 'builtins' 

上面栗子中在第一次調(diào)用b的時候報錯NameError,之后我們修改 builtins 的名字空間,將名字b與值"builtins"進行關(guān)聯(lián),就可以正常調(diào)用了。這種非常規(guī)用法不建議使用。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 文登市| 榕江县| 贵港市| 清徐县| 普安县| 闵行区| 清涧县| 伊春市| 婺源县| 淮阳县| 封开县| 旺苍县| 基隆市| 子长县| 福泉市| 巴马| 廊坊市| 英超| 白银市| 邯郸县| 中西区| 田林县| 云龙县| 牙克石市| 和平区| 鹿邑县| 商城县| 澄城县| 通州市| 讷河市| 霞浦县| 珲春市| 平顺县| 阳原县| 娱乐| 睢宁县| 沾化县| 攀枝花市| 德格县| 宜都市| 陆丰市|