一道題看Python的LEGB規(guī)則

LEGB是Python中變量查找的重要概念。本文通過概念和試題的形式,視圖形象的解釋LEGB在Python中的應(yīng)用。

例題

《核心編程(第二版)》變量作用域和命名空間一節(jié)有以下一道題目:

# coding=utf-8
#!/usr/bin/env python

def proc1():
    j,k = 3,4
    print "j == %d and k == %d" % (j,k)
    k = 5

def proc2():
    j = 6
    proc1()
    print "j == %d and k == %d" % (j,k)

k = 7
proc1()
print "j == %d and k == %d" % (j,k)

j = 8
proc2()
print "j == %d and k == %d" % (j,k)

請問輸出結(jié)果是什么?要想解這道題,必須先了解Python中的一些概念。

LEGB

Python 的變量名解析機(jī)制有時稱為LEGB。
L: Local 是函數(shù)內(nèi)的名字空間,包括局部變量和形參
E: Enclosing 外部嵌套函數(shù)的名字空間(閉包中常見)
G: Global 全局變量,函數(shù)定義所在模塊的名字空間
B: Builtin 內(nèi)置模塊的名字空間

查找的順序?yàn)椋篖--->E--->G--->B


LEGB

查找一個x 的變量,Python 首先在函數(shù)內(nèi)部,局部(Local)范圍來查找這個變量;
如果沒有找到,則到包含這個函數(shù)定義的外圍去查找(稱作 Enclosing),這個外圍或許是另外一個函數(shù)(包括匿名函數(shù))。
如果還是沒有,繼續(xù)朝外查找,一直到模塊級別,從這里定義了全局(Global)變量中尋找;
如果仍然沒有找到,則查找 Python 內(nèi)置變量(Built-in),看是否有相同名字的。
注:在上述查找過程中,一旦變量找到,就不再繼續(xù)朝外圍查找。也就是說 LEGB 同時也定義了從 L 到 B 得優(yōu)先級。

題解

上題目輸出結(jié)果如下:

j == 3 and k == 4
name 'j' is not defined
j == 3 and k == 4
j == 6 and k == 7
j == 8 and k == 7

具體解釋如下:

  1. proc1() 函數(shù)內(nèi)部就有j,k,停止向上查找,故j == 3 and k == 4
  2. print "j == %d and k == %d" % (j,k),程序從上往下執(zhí)行,當(dāng)前只定義k=7,j還未定義,因?yàn)橐呀?jīng)是全局變量了,Builtin中未定義j,因此返回未定義的錯誤。
  3. proc2()中會調(diào)用proc1()依舊先打印j == 3 and k == 4
    proc2()內(nèi)部需要打印,j,k值,j本地已經(jīng)定義為6,k未定義,則向上查找,查找到全局變另種定義了k=7,因此輸出:j == 6 and k == 7
  4. print "j == %d and k == %d" % (j,k),前面的程序已經(jīng)給j,k進(jìn)行了賦值,直接輸出即可,j == 8 and k == 7

來源參考:

理解 Python 的 LEGB
零基礎(chǔ)學(xué)python-16.3 變量名解析:LEGB原則


本文由 EverFighting 創(chuàng)作,采用 **知識共享署名 3.0 中國大陸許可協(xié)議 **進(jìn)行許可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗(yàn)。 張土汪:刷leetcod...
    土汪閱讀 12,901評論 0 33
  • 個人筆記,方便自己查閱使用 Py.LangSpec.Contents Refs Built-in Closure ...
    freenik閱讀 67,945評論 0 5
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,644評論 18 399
  • 2017年04月28日 今天是寫一點(diǎn)記錄的第140天了,從2016年的12月10日開始,一直用“錘子標(biāo)簽”在寫,真...
    西瓜大寶他爹閱讀 382評論 1 1
  • 以前聽老師講解事件冒泡和事件捕獲機(jī)制的時候跟聽天書一樣,只依稀記得IE使用的是事件冒泡,其他瀏覽器則是事件捕獲。當(dāng)...
    web蝸牛閱讀 2,680評論 0 1

友情鏈接更多精彩內(nèi)容