python 作用域 前缀_Python 之作用域和名字空间
作用域與名字空間
Python有一個核心概念是名字空間(namespace),namespace是一個name到object 的映射關系,Python有很多namespace,因此,在代碼中如果碰到一個標志符(name),需要有一個規則來決定去哪個namespace查找——這就是LEGB。
LEGB決定了name的查找順序:locals -> enclosing function -> globals -> __builtins__
locals 是函數內的名字空間,包括局部變量和形參;
enclosing 外部嵌套函數的名字空間(閉包中常見);
globals 全局變量,函數定義所在模塊的名字空間;
builtins 內置模塊的名字空間;
所以,在 Python 中檢索一個變量的時候,優先到 locals 里面來檢索,檢索不到的情況下會檢索 enclosing ,enclosing 沒有則到 globals 全局變量里面檢索,最后是到 builtins 里面來檢索。
當然,因為 builtins 的特殊性,我們可以直接在 builtins 里面添加變量,這樣就可以在任意模塊中訪問變量,不過這種方法太過于變態,不推薦這么做。
LGB規則(閉包是一種特殊的作用域,暫不考慮)與name space加載的順序相反,Python解釋器初始化的時候會先加載built-in namespace,它由__builtins__模塊的名字構成,隨后加載global namespace。 如果在執行期間調用了一個函數,那么將創建局部名字空間。
Python中一切都是object,包括function、module、class、package,這些objects都有在內存中真真正正的存在。每個object都有自己的namespace,每個object的namespace是獨立的,可以通過object.name的方式訪問object的namespace中的name,因此,不同的namespace中可以使用相同的name,而不會引發混淆。namespace是動態創建的,每一個namespace的生存時間也不一樣。例如,一個module的namespace是它被import的時候創建的。而function被調用時,創建其local namespace,調用結束或拋出exception的時候, 該local namespace將被刪除。
locals( )和globals( )分別返回dictionary結構的global namespace和local namespace,例如:
a = 3
defproc():
a= 3
print(locals())print(globals())
proc()
可以看見,局部作用域和全局作用域都有變量a,但它們不是同一個對象。
注意:還有一個特殊的module,一進入python解釋器,就建立了一個module,這個module的namespace就是global namespace,一個全局唯一的namespace。這個module的一個內部的attribute,__name__等于__main__。如果模塊是被導入的,__name__的值為模塊的名字;如果模塊是被直接執行的,__name__的值為’__main__’。
scope(作用域):用unqualified reference name(即與object.name相比,沒有object的前綴)就可以直接找到name所指的對象。 LGB規則用scope的概念來解釋就是:在任何代碼執行的時候,都至少有3個scope,從內到外一次查找一個unqualified reference name。
函數體內的局部變量和全局變量如果重名,全局變量不可見(被局部變量覆蓋)。
x = 50
deffunc(x):print('x=', x) #50
x = 2
print('x=', x) #2
func(x)print('x=', x) #50
一個更復雜的例子:
j, k = 1, 2
defproc1():
j, k= 3, 4
print "j==%d and k=%d" %(j,k)
k= 5
defproc2():
j= 6proc1()print "j==%d and k=%d" %(j,k)
k= 7proc1()print "j==%d and k=%d" %(j,k)
j= 8proc2()print "j==%d and k=%d" %(j,k)
當在函數中需要修改全局變量時,如果沒有global關鍵字則會出錯:
x = 50
defrun():printx
x= 2run()
報錯為:UnboundLocalError: local variable 'x' referenced before assignment
加上global關鍵字以后則OK
x = 50
defrun():globalx
x= 2run()print x #2
總結
以上是生活随笔為你收集整理的python 作用域 前缀_Python 之作用域和名字空间的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何让控件span的id调用ajax_微
- 下一篇: python httpstr find_