1. 程式人生 > >【轉】Python 內建函式 locals() 和globals()

【轉】Python 內建函式 locals() 和globals()

Python 內建函式 locals() 和globals()

轉自: https://blog.csdn.net/sxingming/article/details/52061630 1》這兩個函式主要提供, 基於字典的訪問區域性變數和全域性變數的方式
python 使用叫做名字空間的東西來記錄變數的軌跡。 名字空間是一個字典 ,它的鍵就是字串形式的變數名字,它的值就是變數的實際值
名字空間可以像 Python 的 dictionary 一樣進行訪問。
在一個 Python 程式中的任何一個地方,都存在幾個可用的名字空間。
每個函式都有著自已的名字空間,叫做 區域性名字空間
,它記錄了函式的變數,包括函式的引數和區域性定義的變數。
每個模組擁有它自已的名字空間,叫做 全域性名字空間,它記錄了模組的變數,包括函式、類、其它匯入的模組、模組級的變數和常量。
還有就是 內建名字空間, 任何模組均可訪問它,它存放著內建的函式和異常。
2》當一行程式碼要使用變數 x 的值時,Python 會到所有可用的名字空間去查詢變數,按照如下順序:
區域性名字空間 - 特指當前函式或類的方法。如果函式定義了一個區域性變數 x, 或一個引數 x,Python 將使用它,然後停止搜尋。
全域性名字空間 - 特指當前的模組。如果模組定義了一個名為 x 的變數,函式或類,Python 將使用它然後停止搜尋。
內建名字空間 - 對每個模組都是全域性的。作為最後的嘗試,Python 將假設 x 是內建函式或變數。
如果 Python 在這些名字空間找不到 x,它將放棄查詢並引發一個 NameError 異常,
同時傳遞 There is no variable named 'x' 這樣一條資訊.
3》名字空間在執行時直接可以訪問。區域性名字空間可以通過內建的 locals 函式來訪問。全域性 (模組級別) 名字空間可以通過內建的 globals 函式來訪問。
locals 對區域性 (函式) 名字空間做了些什麼,globals 就對全域性 (模組) 名字空間做了什麼。
然而 globals 更令人興奮,因為一個模組的名字空間包含了模組級的變數和常量,它還包括了所有在模組中定義的函式和類,以及任何被匯入到模組中的東西。
4》回想一下 from module import 和 import module 之間的不同?
使用 import module,模組自身被匯入,但是它保持著自已的名字空間,
這就是為什麼您需要使用模組名來訪問它的函式或屬性: module.function 的原因。
但是使用 from module import,實際上是從另一個模組中將指定的函式和屬性匯入到您自己的名字空間,
這就是為什麼您可以直接訪問它們卻不需要引用它們所來源的模組的原因。
使用 globals 函式,您會真切地看到這一切的發生。
5》locals()例項:
def
foo(arg, a): x = 100 y = 'hello python!' for i in range(10): j = 1 k = i print locals() foo(1,2)
結果:
{'a': 2, 'i': 9, 'k': 9, 'j': 1, 'arg': 1, 'y': 'hello python!', 'x': 100}

6》locals 是隻讀的,不可修改, 而globals可以修改,原因是:
locals()實際上沒有返回區域性名字空間,它返回的是一個拷貝
。所以對它進行修改,修改的是拷貝,而對實際的區域性名字空間中的變數值並無影響。
globals()返回的是實際的全域性名字空間,而不是一個拷貝: 與 locals 的行為完全相反。

所以對 globals 所返回的 dictionary 的任何的改動都會直接影響到全域性變數的取值。

#!/usr/bin/env python    
#coding:utf-8    
'''This is my first python program!'''    
z = 7 #定義全域性變數  
def foo(arg):   
    x = 1   
    print locals()  
    print 'x=',x  
    locals()['x'] = 2 #修改的是區域性名字空間的拷貝,而實際的區域性名字空間中的變數值並無影響。  
    print locals()  
    print "x=",x  
  
foo(3)   
print globals()  
print 'z=',z  
globals()["z"] = 8 #globals()返回的是實際的全域性名字空間,修改變數z的值  
print globals()  
print "z=",z  
結果:
{'x': 1, 'arg': 3}
x= 1
{'x': 1, 'arg': 3}
x= 1
{'foo': <function foo at 0x02A17CF0>, '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'E:\\workspace\\python day03\\main\\test.py', '__package__': None, '__name__': '__main__', 'z': 7, '__doc__': 'This is my first python program!'}
z= 7
{'foo': <function foo at 0x02A17CF0>, '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'E:\\workspace\\python day03\\main\\test.py', '__package__': None, '__name__': '__main__', 'z': 8, '__doc__': 'This is my first python program!'}
z= 8

(完)

  • 判斷一個變數是否存在
res1 = 'test' in locals().keys()
res2 = 'test' in dir()
res3 = 'test' in vars().keys()
print(res1,res2,res3)  # 變數test暫時還沒有定義,返回False
test = ""  # 定義變數test
res4 = 'test' in locals().keys()
res5 = 'test' in dir()
res6 = 'test' in vars().keys()
print(res4,res5,res6)  # 變數test已經被定義了,返回True