您好,登錄后才能下訂單哦!
小編這次要給大家分享的是詳解Python命名空間namespace及作用域原理,文章內容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。
曾經學C++的時候,經常聽到這個名詞,它主要是為了避免命名沖突而產生的。
就像有A(4個蘋果),B(6個蘋果)兩個人,10個蘋果,如果只標簽了蘋果,你無法判斷哪個蘋果是屬于哪個人的,因為標簽都是一樣的;但是如果標簽是A.蘋果,B.蘋果,那么是不是很容易就知道了蘋果是誰的了。
命名空間:提供了一種從名稱到對象的映射;主要是通過字典來實現的。
在python中,函數、模塊等都有自己的命名空間:
局部命名空間(local namespace):即函數中定義的名稱 —— 包括函數中的變量、參數、局部變量等;
全局命名空間(global namespace):即模塊中定義的名稱 —— 包括模塊中的變量、函數、類、參數、常量、導入(import)的模塊等;
內置命名空間(built-in namespace):即python內置的名稱 —— 包括各種內置函數、Exception等;
而,當python需要使用變量時,會在上述命名空間中依次查找,順序是:
局部命名空間,全局命名空間、內置命名空間。
同一命名空間中不能有重名,但不同命名空間可以。
可以通過locals()、globals() 函數來獲取命名空間的值(字典),在程序的不同位置執行結果不一定一致,因為結果是針對當前位置來說的。
locals()
globals()
可以通過字典形式獲取其中的值:
作用域:可以理解為變量所起作用的范圍,超出范圍則某變量不能被使用。在python 程序中,直接訪問一個變量,會從內到外依次訪問所有的作用域直到找到,否則報錯。Python 中只有模塊(module),類(class)以及函數(def、lambda)才會產生新的作用域,其它的代碼塊(如 if/elif/else/、try/except、for/while等)是不會產生新的作用域的。
作用域可以分為四種:
Local:最內層,包含局部變量,一般指的是函數內部的作用域;
Enclosing:包含非局部但是也不是全局的變量,主要是嵌套時,外層函數的變量,那么相對內層函數來說,嵌套的外層函數中的變量既不是局部變量也不是全局變量。
Global:全局變量,例如當前模塊中的全局變量。
Build-in:內置變量。
查找順序一般是:Local--->Enclosing--->Global--->Build-in
def test1(): x1 = 1 #Enclosing 作用域 def test2(): x2 = 1 #Local 作用域 print('x2=',x2) x1 = 100 #很明顯,外層作用域中的x1沒有受到影響,因為這里的x1屬于Local test2() return x1 aa = test1() print('aa=',aa)
要想修改外層作用域(上層)的變量,需要用到global和nonlocal關鍵字。(注意,修改和訪問不是一樣的程度)
def test1(): x1 = 1 #Enclosing 作用域 def test2(): x2 = 1 #Local 作用域 print('x2=',x2) nonlocal x1 x1 = 100 #通過nonlocal,將這里的x1作用域變化為Enclosing作用域,即影響到Enclosing作用域中的x1的值 test2() return x1 aa = test1() print('aa=',aa)
def test1(): x1 = 1 # 這個x1屬于Enclosing 作用域 def test2(): x2 = 1 #Local 作用域 print('x2=',x2) global x1 # 這個x1屬于全局作用域 x1 = 100 #這里影響的是全局作用域中的x1值,并不會影響到Enclosing作用域中的值 test2() return x1 #返回的是當前作用域Enclosing中的x1的值 aa = test1() print('aa=',aa) print('x1=',x1)
全局變量和局部變量
定義在函數內部的變量,擁有局部作用域,屬于局部變量。
定義在函數外部的變量,擁有全局作用域,屬于全局變量。
全局變量可以在整個全局作用域內訪問,但是要修改的話,需要用到global關鍵字。
更細節一點,若涉及到class:
全局變量:一般在模塊內、在所有函數外面、在class外面的變量。
局部變量:一般在函數內、在class的方法內(未加self修飾)的變量。
看完這篇關于詳解Python命名空間namespace及作用域原理的文章,如果覺得文章內容寫得不錯的話,可以把它分享出去給更多人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。