python學習彙總40:名稱空間和作用域及local,global,locals(),globals()區別 2018/11/16(推薦)tcy
阿新 • • 發佈:2019-01-11
python名稱空間和作用域及local,global,locals(),globals()區別 2018/11/16
目錄:
1.名稱空間及作用域的基本概念
1.1.模組級變數運用
2.變數的作用域
3.local,global,locals(),globals()區別
loccals檢視區域性變數
globals檢視修改刪除全域性變數
4.典型錯誤處理
1.1.名稱空間分類: 全域性名稱空間:記錄模組變數,包括函式、類、匯入模組、模組級變數和常量 區域性名稱空間:函式,類,推導式名字空間叫做區域性名字空間,記錄引數和區域性變數 內建名稱空間:任何模組均可訪問它,存放著內建函式異常
1.2.三種名稱空間之間的載入與取值順序: 載入順序: 內建名稱空間(程式執行前載入)->全域性名稱空間(程式執行中:從上到下載入)->區域性名稱空間(程式執行中:呼叫時才載入) 取值 ,查詢變數順序: 區域性名稱空間->全域性名稱空間->內建名稱空間 區域性名字空間local 本地- 特指當前函式或類方法。 區域性名字空間 Eclosing封閉- 函式體內定義函式 全域性名字空間global全域性 - 特指當前模組。 內建名字空間 built-in內建- 對每個模組都是全域性的。 注意: import module:模組自身被導,保持自已名字空間;module.function在模組的名稱空間中運用 from module import: 將module.function函式屬性匯入當前名字空間;可以直接使用
1.3.python程式碼執行函式機理 python直譯器開始執行之後,在記憶體中開闢一個空間,當遇到一個變數時把變數名和值 之間對應關係記錄下來。當遇到函式定義時直譯器只是象徵性將函式名讀入記憶體,表示知 道這個函式存在,至於函式內部的變數和邏輯直譯器根本不關心 程式碼在執行伊始,建立的儲存“變數名與值的關係”的空間叫做全域性名稱空間 等執行到函式呼叫的時候,python直譯器會再開闢一塊記憶體來儲存這個函式裡的內容, 這個時候,才關注函式裡面有哪些變數,而函式中的變數會儲存在新開闢出來的記憶體中。 函式中變數只能在函式內部使用,隨著函式執行完畢這塊記憶體中所有內容被清空 在函式的執行中開闢的臨時的空間叫做區域性名稱空間 內建名稱空間存放python直譯器提供名字input print str list tuple.等.可直接使用。
2.變數的作用域
概念:
global變數:為全域性作用域;
nonlocal變數:為封閉作用域,系統每次執行函式時會建立新的區域性名稱空間
globals() :以字典型別返回當前位置的全部全域性變數。
locals() :以字典型別返回當前位置的全部區域性變數
用途:
用於定義,檢視,修改變數
注意:
1)golbal用於定義全域性變數
2)nonlocal用於函式內定義區域性變數
3)globals,locals函式用名字空間來記錄變數軌跡;名字空間是一個字典 {變數名:變數值}
4)名字空間在執行時直接可以訪問,可在名稱空間中更改變數
(1)區域性名字空間可通過內建locals函式訪問; locals是隻讀 不可修改;locals()返回的拷貝;修改不影響區域性名字空間中變數值
(2)全域性(模組級別)名字空間可通過內建globals函式來訪問;globals可以修改,返回全域性名字空間;對他修改影響全域性變數
5).跨模組共享全域性變數
在單個程式中跨模組共享資訊的規範方式是建立一個特殊模組(通常稱為config或cfg)。
只需在應用程式的所有模組中匯入配置模組; 該模組將成為全域性名稱。由於每個模組只有
一個例項,因此對模組物件所做的任何更改都會反映到處。例如:
config.py:
x = 0 # Default value of the 'x' configuration setting
mod.py:
import config
config.x = 1
main.py:
import config
import mod
print(config.x)
3.例項 :
例項1-locals()檢視區域性變數
def add_tcy(a,b):
z=a+b
s=locals()
locals()['z'] = -100 # 修改區域性名字空間拷貝變數無影響
return s['z'],z,s
f=add_tcy(3,4) # (-100, 7, {'a': 3, 'b': 4, 'z': -100, 's': {...}})#z並未改變,改變的locals()拷貝的副本
例項2-globals()檢視修改刪除全域性變數
import os
'name' in globals() #False
globals()['name']=os.getcwd()#'C:\\python37\\Scripts'
'name' in globals() #True
del globals()['name']
'name' in globals() # False
例項3-globals()在名稱空間中修改全域性變數
x,y=10,20
z=x+y
print(z)#30
globals()['x']=-100 # globals()修改變數x的值為-100
z=x+y
print(z)#80
4.例項:測試全域性變數和區域性變數
顯示函式定義:
lst=[0,0]
def view_variable(locals,globals,lst=lst):
'''僅顯示變數,去除其他顯示'''
def ChooseVariable(data):
d={}
for key,value in data.items():
if ('__' not in key) and (not isinstance(value,dict)) and('lst' not in key):
if 'function' in str(value):value='fun'
d[key]=value
lst[1]=lst[1]+1
lst[0]=(lst[0]+1) if (lst[1]%2)==0 else lst[0]
return d
print('{}.1.locals={}'.format(lst[0],ChooseVariable(locals)))
print('{}.2.globals={}'.format(lst[0],ChooseVariable(globals)))
例項1:
g_x0=1 #全域性作用域
l=locals()
g=globals()
view_variable(l,g)
# 1.locals={'view_variable': 'fun', 'g_x0': 1}
# 2.globals={'view_variable': 'fun', 'g_x0': 1}
例項2:測試全域性變數和區域性變數---閉包變數測試
g1=-1000
def test_func():
V0=10 #作用域為test_func函式
l = locals()
g = globals()
view_variable(l, g)
# 0.1.locals={'V0': 10}
# 0.2.globals={'view_variable': 'fun', 'g1': -1000, 'test_func': 'fun'}
def local_func():
V0 = 20 #作用域為本函式
l = locals()
g = globals()
view_variable(l, g)
# 1.1.locals={'V0': 20}
# 1.2.globals={'view_variable': 'fun', 'g1': -1000, 'test_func': 'fun'}
def nonlocal_func():
nonlocal V0 #作用域為test_func函式內部
V0=15
l = locals()
g = globals()
view_variable(l, g)
# 2.1.locals={'V0': 15}
# 2.2.globals={'view_variable': 'fun', 'g1': -1000, 'test_func': 'fun'}
def global_func():
global V0 #新建global全域性變數
V0=-1
l = locals()
g = globals()
view_variable(l, g)
# 3.1.locals={}
# 3.2.globals={'view_variable': 'fun', 'g1': -1000, 'test_func': 'fun', 'V0': -1}
local_func()
print("V0=:", V0) # V0=10
nonlocal_func()
print("V0=:", V0) #V0=15
global_func()
print("V0=", V0) #同名內部優先V0=15
l = locals()
g = globals()
view_variable(l, g)
# 4.1.locals={'V0': 15, 'local_func': 'fun', 'nonlocal_func': 'fun', 'global_func': 'fun'}
# 4.2.globals={'view_variable': 'fun', 'g1': -1000, 'test_func': 'fun', 'V0': -1}
測試呼叫
test_func()
print(V0) #V0=-1
l=locals()
g=globals()
view_variable(l,g)
# 5.1.locals={'view_variable': 'fun', 'g1': -1000, 'test_func': 'fun', 'V0': -1}
# 5.2.globals={'view_variable': 'fun', 'g1': -1000, 'test_func': 'fun', 'V0': -1}
5.錯誤處理:
例項1
def myFunction(param1=123,param2="Python"):
# global myVar
for key,val in locals().items():
print( "key==> (%s : %s)" % (key,str(val)))
myVar = myVar + 1
myVar = 27
myFunction(12,'Tom')
#預設global myVar程式報錯
#輸出:
# key==> (param1 : 12)
# key==> (param2 : Tom)
#報錯原因:區域性賦值需要注意
Python有如下假設,如果在函式體內的任何地方對變數賦值,則Python將名稱新增到區域性名稱空間。
語句myVar = myVar + 1對名稱myVar進行賦值,Python假設無論在何處發生賦值,myVar都是函式myFunction區域性名稱空間的一部分。
當Python嘗試把1新增到myVar中時,該名稱在區域性名稱空間中,但它沒有關聯值,因此報錯。
問題在於Python何時決定myVar出現在區域性空間中,這發生在程式碼執行之前,即,在Python執行到函式定義之前。由於建立區域性名稱空間時
(程式碼實際執行之前)。Python會檢查程式碼並填充區域性名稱空間。在Python執行那行程式碼前,就發現了對myVar的賦值,並把它新增到區域性
名稱空間中。當函式執行時,Python直譯器認為myVar在區域性名稱空間中但沒有值,所以會產生錯誤。
解決辦法:
如果在函式體內,使用global語句將變數宣告為全域性變數,那麼Python不會為該變數在名稱空間中建立區域性名稱。
例項2:典型內部變數運用錯誤
def a(x):
print(x)
def b():
print(x) #報錯,函式內賦值操作對外層變數遮蔽,無論賦值引數在本函式內部位置何處
x = 20
print(x)
return b
f=a(10)()
print(f)
解決辦法 :
def a(x):
print(x)
def b():
nonlocal x # python3 的 nonlocal 語句可以內部函式直接使用外部函式
print(x) #報錯,函式內賦值操作對外層變數遮蔽,無論賦值引數在本函式內部位置何處
x = 20
print(x)
return b
f=a(10)()
print(f)
# 10
# 10
# 20
# None