解读Python的命名空间
前面我們理解了變量、函數(shù)的作用域,現(xiàn)在我們再深入討論一下Python是如何給變量、函數(shù)劃分作用域的。
我們在編寫Python程序的過程中,如果要使用變量和函數(shù),都需要先對變量和函數(shù)命名后才能使用。Python會把命名后的變量和函數(shù)分配到不同的命名空間,并通過名稱來識別它們。Python為什么要區(qū)分不同的命名空間呢?它有兩個作用:一個作用是不同的命名空間對應(yīng)不同的作用域;另外一個作用是防止命名沖突。
我們先來看第一個作用。前面我們已經(jīng)知道了在函數(shù)內(nèi)部聲明的變量屬于局部變量,在模塊內(nèi)部聲明的變量屬于全局變量。Python是如何確定哪個變量是屬于全局還是局部呢?這就需要用到命名空間概念了。
Python會把在函數(shù)內(nèi)部聲明的變量放置到局部命名空間,把在模塊聲明的變量放置到全局命名空間。在局部命名空間的變量其作用域只能是在函數(shù)內(nèi)部范圍,在全局命名空間的變量其作用域?yàn)檎麄€模塊。函數(shù)的命名也同樣適用于局部命名空間和全局命名空間,嵌套函數(shù)的命名是放置在局部命名空間的,因此其作用域只能在父函數(shù)范圍;而父函數(shù)的命名是放置在全局命名空間的,因此其作用域適用于整個模塊。
關(guān)于命名空間的作用域,這里面還有一個問題。那就是在模塊或函數(shù)中使用的Python自身提供的內(nèi)建函數(shù),它是屬于哪個命名空間呢?因?yàn)檫@些內(nèi)建函數(shù)在模塊中隨意使用,沒有作用域的限制。其實(shí)Python還為自己的函數(shù)、程序提供了一個命名空間,這個命名空間是內(nèi)置命名空間,在內(nèi)置命名空間放置的變量、函數(shù),在整個Python程序模塊中都可以被訪問,其作用域是整個程序。
小結(jié)一下,在Python程序執(zhí)行過程中,會有局部命名空間、全局命名空間和內(nèi)建命名空間同時(shí)存在。局部命名空間記錄函數(shù)內(nèi)部的變量、傳入函數(shù)的參數(shù)、嵌套函數(shù)等被命名的對象;全局命名空間記錄模塊的變量、函數(shù)、類及其它導(dǎo)入的模塊等被命名的對象;內(nèi)建命名空間記錄Python自身提供的函數(shù)、模塊等被命名的對象。
我們再來看命名空間的第二個作用。命名空間可以預(yù)防變量和函數(shù)的命名沖突。前面我們知道了Python有三類命名空間,分別是局部命名空間、全局命名空間和內(nèi)建命名空間。Python在編譯和解釋執(zhí)行Python代碼的過程中,會為每個模塊建立一個全局命名空間,為模塊中的每個函數(shù)建立局部命名空間。相當(dāng)于Python為程序的每個模塊和函數(shù)提供了一個封閉的命名空間,在這個封閉的命名空間中,函數(shù)及變量命名互相不受影響,在不同的模塊中可以聲明相同名稱的函數(shù),在不同的函數(shù)中可以聲明相同名稱的變量,雖然它們的名稱相同,但它們之間沒有任何聯(lián)系。
那么Python如何把已命名的變量及函數(shù)的作用域和命名空間聯(lián)系起來了呢?它所要做的就是在命名空間查詢變量或函數(shù)的名稱。Python訪問一個已命名的變量或函數(shù)時(shí),它會從三個命名空間中查詢。首先從局部命名空間開始,如果沒有找到,它就會繼續(xù)查找全局命名空間,如果在全局命名空間中也沒找到,它將在內(nèi)建命名空間里查找。如果這些查找都失敗了,它將會報(bào)出下面的錯誤。
在Python解釋器中,我們輸入了foo,沒有給foo進(jìn)行賦值(聲明變量時(shí)需要進(jìn)行賦值)。解釋器會從命名空間中查找foo,它先從局部空間查找,如果找到了它就會使用局部命名空間的變量foo,即使全局命名空間也有變量foo。這就很容易理解為什么在函數(shù)內(nèi)部聲明的局部變量會覆蓋掉在模塊中聲明的同名變量。
Python提供了內(nèi)建函數(shù)可以輸出命名空間里面的內(nèi)容。輸出局部命名空間的內(nèi)容使用locals()函數(shù),輸出全局命名空間的的內(nèi)容使用globals()函數(shù)。
上面的代碼給出了如何訪問局部命名空間和全局命名空間的內(nèi)容,命名空間的內(nèi)容以字典形式給出,字典的key是已命名的變量或函數(shù)名稱,value是這些變量或函數(shù)的值。從輸出內(nèi)容可以看出,局部變量的π覆蓋了全局變量的π。下圖是輸出結(jié)果。
總結(jié)
以上是生活随笔為你收集整理的解读Python的命名空间的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux问题
- 下一篇: linux sh 改 cmd