成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

理解 Python 的 LEGB

FrozenMap / 2937人閱讀

摘要:理解的名字空間的名字空間是一個(gè)非常核心的內(nèi)容。在中提供了一個(gè)關(guān)鍵字來(lái)修改外部嵌套函數(shù)的名字空間,但是要使用才有,我等使用的只能眼饞一下。

理解 Python 的 LEGB 名字空間

Python 的名字空間是 Python 一個(gè)非常核心的內(nèi)容。
其他語(yǔ)言中如 C 中,變量名是內(nèi)存地址的別名,而在 Python 中,名字是一個(gè)字符串對(duì)象,它與他指向的對(duì)象構(gòu)成一個(gè){name:object}關(guān)聯(lián)。
Python 由很多名字空間,而 LEGB 則是名字空間的一種查找規(guī)則。

作用域

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

舉個(gè)栗子,來(lái)說(shuō)明作用域是相互獨(dú)立的。


In [11]: i = "G" In [12]: def test(): i = "L" print i, "in locals" ....: In [13]: test() L in locals In [14]: print i, "in globals" G in globals

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

簡(jiǎn)述

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

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

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

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

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

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

當(dāng)然,因?yàn)?builtins 的特殊性,我們可以直接在 builtins 里面添加變量,這樣就可以在任意模塊中訪問(wèn)變量,不過(guò)這種方法太過(guò)于{{BANNED}},不推薦這么做。

locals,globals

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

In [1]: def f(x):
   ...:     a = x
   ...:     print a
   ...:     print locals()
   ...:


In [2]: f("hello")
hello
{"a": "hello", "x": "hello"}

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

In [6]: def f(x):
   ...:     global a
   ...:     a = x
   ...:     print a
   ...:     print locals()
   ...:

In [7]: f("hello")
hello
{"x": "hello"}

In [8]: print a
hello

In [9]: print x
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
 in ()
----> 1 print x

NameError: name "x" is not defined

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

Enclosed

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

In [11]: def outer():
   ....:     a_var = "enclosed value"
   ....:     print a_var
   ....:     def inner():
   ....:         a_var = "local value"
   ....:         print(a_var)
   ....:     inner()
   ....:     print a_var
   ....:

In [12]: outer()
enclosed value
local value
enclosed value

下面的栗子簡(jiǎn)單示范一下 nonlocal 的用法,實(shí)在 Python3下面才可以正常運(yùn)行的:

In [1]: a_var = "global value"

In [2]: def outer():
   ...:     a_var = "local value"
   ...:     print("outer befor", a_var)
   ...:     def inner():
   ...:         nonlocal a_var
   ...:         a_var = "inner value"
   ...:         print("in inner():", a_var)
   ...:     inner()
   ...:     print("outer inner:", a_var)
   ...:

In [3]: outer()
outer befor local value
in inner(): inner value
outer inner: inner value

In [4]: print(a_var)
global value
builtins

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

In [19]: b
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
 in ()
----> 1 b

NameError: name "b" is not defined

In [20]: __builtins__.b = "builtins"

In [21]: b
Out[21]: "builtins"

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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/37330.html

相關(guān)文章

  • 一道題看PythonLEGB規(guī)則

    摘要:例題核心編程第二版變量作用域和命名空間一節(jié)有以下一道題目請(qǐng)問(wèn)輸出結(jié)果是什么要想解這道題,必須先了解中的一些概念的變量名解析機(jī)制有時(shí)稱為。 例題 《核心編程(第二版)》變量作用域和命名空間一節(jié)有以下一道題目 # coding=utf-8 #!/usr/bin/env python def proc1(): j,k = 3,4 print j == %d and k ==...

    iamyoung001 評(píng)論0 收藏0
  • Python: 作用域(scope) 和 LEGB

    摘要:約束名字空間作用域之間的那些事不管在什么編程語(yǔ)言都有作用域這個(gè)概念作用域控制在它范圍內(nèi)代碼的生存周期包括名字和實(shí)體的綁定名字和實(shí)體的綁定我們可以理解成賦值當(dāng)我們執(zhí)行這句代碼時(shí)實(shí)際上我們已經(jīng)得到一個(gè)的關(guān)聯(lián)關(guān)系我們也能將稱之為約束這個(gè)約束也將存 約束 名字空間 作用域 之間的那些事 不管在什么編程語(yǔ)言, 都有作用域這個(gè)概念.作用域控制在它范圍內(nèi)代碼的生存周期, 包括名字和實(shí)體的綁定. 名字...

    JayChen 評(píng)論0 收藏0
  • Python 命名空間

    摘要:真正管理這些名子的事物就是本文的主角命名空間。閉包命名空間閉包函數(shù)的名稱空間引入。函數(shù)調(diào)用時(shí)產(chǎn)生新的局部命名空間函數(shù)返回結(jié)果拋出異常時(shí)釋放命名空間,每一次遞歸都生成一個(gè)命名空間。標(biāo)識(shí)符產(chǎn)生地點(diǎn)決定標(biāo)識(shí)符所處的命名空間。 懶得掃全文的童鞋,可以直接跳到最后看總結(jié)。我們先從一個(gè)簡(jiǎn)單的栗子說(shuō)起: 栗子 a 文件中有變量 va 以及類 A,b 文件導(dǎo)入 a 中class A ,并打印出 A: ...

    ralap 評(píng)論0 收藏0
  • 由一個(gè)例子到python名字空間

    摘要:當(dāng)程序引用某個(gè)變量的名字時(shí),就會(huì)從當(dāng)前名字空間開(kāi)始搜索。對(duì)于可以看出已經(jīng)被導(dǎo)入到自己的名字空間了,而不是在里面。因此并沒(méi)有涉及到修改名字空間。按照原則,搜到有變量并且是個(gè)然后將其加入到自己的后面的就開(kāi)始讀取的元素,并沒(méi)有影響的名字空間。 源自我的博客 前言 python里面最核心的內(nèi)容就是:名字空間(namespace) 例子引入 例1 #!/usr/bin/env python #...

    XiNGRZ 評(píng)論0 收藏0
  • python變量與變量作用域

    摘要:在函數(shù)中執(zhí)行賦值操作時(shí),會(huì)創(chuàng)建一個(gè)局部變量,如果想在函數(shù)中通過(guò)賦值改變一個(gè)全局變量,則需要用關(guān)鍵字申明,只要出現(xiàn)了操作符,則這個(gè)變量就是局部變量,除非顯示申明為。 python變量與變量作用域 c語(yǔ)言中,變量的定義會(huì)為變量分配一塊內(nèi)存,變量的內(nèi)存地址不會(huì)發(fā)生改變,當(dāng)變量的值發(fā)生改變時(shí),改變的是對(duì)應(yīng)內(nèi)存地址中的值。 python中,給變量賦值時(shí),變量保存的是一個(gè)對(duì)象的引用,如果想改變變...

    chavesgu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<