學習地址:http://www.jianshu.com/p/17a9d8584530python
在Python程序中建立、改變、查找變量名時,都是在一個保存變量名的空間中進行,咱們稱之爲命名空間,也被稱之爲做用域。python的做用域是靜態的,在源代碼中變量名被賦值的位置決定了該變量能被訪問的範圍。即Python變量的做用域由變量所在源代碼中的位置決定。閉包
通常的高級語言在使用變量時,都會有下面4個過程。固然在不一樣的語言中也會有着區別。編輯器
就做用域而言,Python與C有着很大的區別,在Python中並非全部的語句塊中都會產生做用域。只有當變量在Module(模塊)、Class(類)、def(函數)中定義的時候,纔會有做用域的概念。看下面的代碼:函數
#!/usr/bin/env python def func(): variable = 100 print variable print variable
代碼的輸出爲:學習
NameError: name 'variable' is not defined
在做用域中定義的變量,通常只在做用域中有效。 須要注意的是:在if-elif-else、for-else、while、try-except\try-finally等關鍵字的語句塊中並不會產成做用域。看下面的代碼:ui
if True: variable = 100 print (variable) print ("******") print (variable)
代碼的輸出爲:spa
100 ****** 100
因此,能夠看到,雖然是在if語句中定義的variable變量,可是在if語句外部仍然可以使用。code
在Python中,使用一個變量時並不嚴格要求須要預先聲明它,可是在真正使用它以前,它必須被綁定到某個內存對象(被定義、賦值);這種變量名的綁定將在當前做用域中引入新的變量,同時屏蔽外層做用域中的同名變量。對象
局部變量:包含在def關鍵字定義的語句塊中,即在函數中定義的變量。每當函數被調用時都會建立一個新的局部做用域。Python中也有遞歸,即本身調用本身,每次調用都會建立一個新的局部命名空間。在函數內部的變量聲明,除非特別的聲明爲全局變量,不然均默認爲局部變量。有些狀況須要在函數內部定義全局變量,這時可使用global關鍵字來聲明變量的做用域爲全局。局部變量域就像一個 棧,僅僅是暫時的存在,依賴建立該局部做用域的函數是否處於活動的狀態。因此,通常建議儘可能少定義全局變量,由於全局變量在模塊文件運行的過程當中會一直存在,佔用內存空間。
注意:若是須要在函數內部對全局變量賦值,須要在函數內部經過global語句聲明該變量爲全局變量。遞歸
E也包含在def關鍵字中,E和L是相對的,E相對於更上層的函數而言也是L。與L的區別在於,對一個函數而言,L是定義在此函數內部的局部做用域,而E是定義在此函數的上一層父級函數的局部做用域。主要是爲了實現Python的閉包,而增長的實現。
即在模塊層次中定義的變量,每個模塊都是一個全局做用域。也就是說,在模塊文件頂層聲明的變量具備全局做用域,從外部開來,模塊的全局變量就是一個模塊對象的屬性。
注意:全局做用域的做用範圍僅限於單個模塊文件內
系統內固定模塊裏定義的變量,如預約義在builtin 模塊內的變量。
搜索變量名的優先級:局部做用域 > 嵌套做用域 > 全局做用域 > 內置做用域
LEGB法則: 當在函數中使用未肯定的變量名時,Python會按照優先級依次搜索4個做用域,以此來肯定該變量名的意義。首先搜索局部做用域(L),以後是上一層嵌套結構中def或lambda函數的嵌套做用域(E),以後是全局做用域(G),最後是內置做用域(B)。按這個查找原則,在第一處找到的地方中止。若是沒有找到,則會出發NameError錯誤。
幾個實例:
1.
def func(): variable = 300 print variable variable = 100 func() #300 print variable #100
2.