2015-05-18 54 views
0

我想寫一個函數,它接收一個本地命名空間字典並更新它。事情是這樣的:從函數內部更新當地人

def UpdateLocals(local_dict): 
    d = {'a':10, 'b':20, 'c':30} 
    local_dict.update(d) 

當我打電話從交互式Python殼它的工作原理沒事此功能,像這樣:

a = 1 
UpdateLocals(locals()) 

# prints 20 
print a 

然而,當我打電話UpdateLocals從一個函數裏面,這不是」 t做我期望的:

def TestUpdateLocals(): 
    a = 1 
    UpdateLocals(locals()) 
    print a 

# prints 1 
TestUpdateLocals() 

我該如何使第二種情況像第一種情況一樣工作?

UPDATE:

Aswin的解釋是有道理的,是對我很有幫助。但是我仍然想要一個機制來更新局部變量。之前,我想出一個不太難看的辦法,我要做到以下幾點:

def LoadDictionary(): 
    return {'a': 10, 'b': 20, 'c': 30} 

def TestUpdateLocals(): 
    a = 1 
    for name, value in LoadDictionary().iteritems(): 
    exec('%s = value' % name) 

當然串語句的結構可以實現自動化,細節可以從用戶隱藏。

+0

爲什麼你甚至想這樣做? [本詞典的內容不應修改;更改可能不會影響解釋器使用的本地變量和自由變量的值._](https://docs.python.org/2.7/library/functions.html?highlight=locals#locals) – Alik

+0

我明白了。謝謝!那麼我怎樣才能更新函數內的變量的本地字典?這是我正在尋找的。 – shaoyl85

+1

你想要達到什麼目標? [XY問題](http://meta.stackexchange。com/a/66378) – Alik

回答

0

這裏沒有更新當地人,因爲在第一種情況下,聲明的變量具有全局範圍。但是當在一個函數中聲明時,變量會在其外部失去作用域。

因此,當地人的原始值()在UpdateLocals函數中沒有改變。

PS:這可能與您的問題沒有關係,但在Python中使用camel case並不是一個好習慣。嘗試使用其他方法。

update_locals()代替UpdateLocals()

編輯爲了回答您的評論的問題:

有一種叫做系統堆棧。在執行代碼期間,該系統堆棧的主要工作是管理局部變量,確保在完成被調用函數的執行後返回正確的語句等,在該堆棧中創建一個新條目, 包含控制器在返回語句後必須返回的行號(或指令號)以及一組新的局部變量。

當控件位於函數內部時,局部變量將從堆棧條目中獲取。因此,這兩個函數中的一組當地人是不一樣的。控件退出函數時,彈出堆棧中的條目。因此,除非這些變量具有全局範圍,否則在函數中所做的更改將被刪除。

+0

謝謝!但是我在函數內部打印'a',爲什麼它仍然失去範圍? – shaoyl85

+1

@ shaoyl85:這就是爲什麼他們被稱爲局部變量。當控制超出函數時,這樣的變量不存在。通過傳遞'locals()'字典,您只需發送一個包含這些值的字典。但改變這並不會改變調用函數 –

+0

中的原始當地人我認爲當調用UpdateLocals時,TestUpdateLocals函數還沒有完成執行,所以「locals字典」仍然在內存中的某處。我可以做一些黑客行爲,例如構建一些語句字符串來手動提取字典中的值並使用它們設置局部變量,然後執行這個構造的語句字符串。這將是醜陋的,我不喜歡這樣做。 – shaoyl85