2017-09-07 82 views
8

模塊包含一個字典以跟蹤其上下文,例如在某個執行點定義的名稱。這本詞典可以通過vars(module)(或module.__dict__)如果module是進口來訪問,或通過對模塊本身的locals內置函數的調用:當地人的字典是什麼時候設置的?

更新,並返回來表示當前本地符號表的字典。

但我發現自己有點困惑,當我嘗試從函數訪問當地人字典。腳本只包含以下的輸出是一個空的字典:

def list_locals(): 
    print(locals()) 

list_locals() 

但在另一方面,如果一個腳本包含完全以下,輸出是預期的字典,包含__name____doc__而另一個模塊級變量:

print(locals()) 

那麼,何時是當地人字典集的內容? 另外,什麼是「更新」在locals函數的定義中的含義?

+0

在模塊級嘗試'print(locals()是globals())' –

+0

@Chris_Rands是的,這是我的混亂的一部分。 –

回答

7

模塊的名稱空間是全局命名空間,通過globals()訪問。沒有單獨的本地名稱空間,所以locals(),函數之外,只是返回全局名稱空間。

只有函數具有本地名稱空間。請注意,locals()是該名稱空間的單向反映;函數的CPython實現高度優化,您不能通過locals()字典添加或更改局部變量。只要命名空間在對該函數的調用之間發生更改,就會更新由locals()返回的字典。

還要注意,像list/dict/set comprehensions,生成器表達式和類體這樣的東西實際上也是作爲函數執行的,儘管使用了不同的命名空間規則。在這種情況下,locals()也將返回單獨的函數本地命名空間。

+1

像往常一樣,清楚明白,謝謝! –

1

如果在同一函數調用期間多次調用locals(),它將返回相同的字典。

>>> def f(): 
...  d = locals() 
...  assert 'd' not in d 
...  locals() 
...  assert 'd' in d 
...  assert d is locals() 
...  print(d) 
... 
>>> f() 
{'d': {...}} 

「更新」,在這種情況下,意味着該詞典的內容進行更新,以反映存在的局部變量的當前範圍,但如果你保持一個參照本字典那麼字典將仍然可以使用。

另請注意,即使您在本函數的過程中可以訪問它,當地人字典也不包含'f'的密鑰。如果不明顯,那是全球性的,而不是本地的。

+0

感謝您對「更新」含義的解釋。雖然我明顯混淆了'locals'和'globals',我會說文檔對這種行爲有些迴避。再次感謝您的澄清。 –

相關問題