【python】locals()、globals()與名字空間

JasonDing1354發表於2015-11-14

名字空間

Python使用叫做名字空間的東西來記錄變數的軌跡。名字空間只是一個字典,它的鍵字就是變數名,字典的值就是那些變數的值。實際上,名字空間可以象Python的字典一樣進行訪問。
在一個Python程式中的任何一個地方,都存在幾個可用的名字空間。每個函式都有著自己的名字空間,叫做區域性名字空間,它記錄了函式的變數,包括函式的引數和區域性定義的變數。每個模組擁有它自己的名字空間,叫做全域性名字空間,它記錄了模組的變數,包括函式、類、其它匯入的模組、模組級的變數和常量。還有就是內建名字空間,任何模組均可訪問它,它存放著內建的函式和異常。

當一行程式碼要使用變數 x 的值時,Python會到所有可用的名字空間去查詢變數,按照如下順序:

1.區域性名字空間 - 特指當前函式或類的方法。如果函式定義了一個區域性變數x,Python將使用這個變數,然後停止搜尋。
2. 全域性名字空間 - 特指當前的模組。如果模組定義了一個名為x的變數,函式或類,Python將使用這個變數然後停止搜尋。
3. 內建名字空間 - 對每個模組都是全域性的。作為最後的嘗試,Python將假設x是內建函式或變數。

locals和globals的區別

locals()是隻讀的。globals()不是。這裡說的只讀,是值對於原有變數的只讀。其實還可以對locals()賦值的。
注意,locals()返回的是當前所在最小名稱空間的區域性變數的一個拷貝。比如說在一個函式中呼叫locals(),那麼返回的將是這個函式內部的區域性變數。記住,locals返回的變數都是原有變數的“拷貝”。

from module importimport module之間的不同。使用import module,模組自身被匯入,但是它保持著自已的名字空間,這就是為什麼你需要使用模組名來訪問它的函式或屬性(module.function)的原因。但是使用 from module import,實際上是從另一個模組中將指定的函式和屬性匯入到你自己的名字空間,這就是為什麼你可以直接訪問它們卻不需要引用它們所來源的模組的原因。

使用locals()的例子

在類的編寫中,__init__方法中常常有類似self.something = something的累贅程式碼,我們可以用locals()方法來自動初始化例項變數。
原先的程式碼是這樣的:

def __init__(self, foo, bar, baz, boom=1, bang=2):
    self.foo = foo
    self.bar = bar
    self.baz = baz
    self.boom = boom
    self.bang = bang

下面是修改之後的程式碼:

# 定義抽取屬性的輔助函式
def attributesFromDict(d):
    self = d.pop('self')
    for n, v in d.iteritems():
        setattr(self, n, v)

# __init__被縮減為一行
def __init__(self, foo, bar, baz, boom=1, bang=2):
    attributesFromDict(locals())

轉載請註明作者Jason Ding及其出處
Github部落格主頁(http://jasonding1354.github.io/)
GitCafe部落格主頁(http://jasonding1354.gitcafe.io/)
CSDN部落格(http://blog.csdn.net/jasonding1354)
簡書主頁(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)
Google搜尋jasonding1354進入我的部落格主頁

相關文章