2010-02-23 59 views
20

我發現它非常有用,能夠在運行時創建新的變量和創造的結果進行處理的字典後,即寫入文件:的Python:使用瓦爾()將一個字符串分配給一個變量

myDict = {} 
for i in range (1,10): 
    temp = "variable"+str(i) 
    vars()[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc. 
    myDict[temp] = vars(temp) 

它創建了我可以用myDict [result1]調用的字典條目[result1:data1]。我一直在使用vars()而沒有真正理解我在做什麼。我把它vars()返回與局部變量的字典,並

瓦爾()[X] = Y

創建[X:Y]的新字典項(?)?

我有一個腳本,我在{input1:data1,input2:data2}準備的字典中傳遞,我使用此方法遍歷所有值,存儲所有結果並將其輸出到文件。這段代碼是在一個類中的函數中,並且正在工作。

我的困惑的根源是,我已經閱讀了如何當地人各個崗位()不應該與被搞砸了,怎麼瓦爾()相當於(?)當地人(),或全局()..

所以我的問題是(至少)兩個方面:

1.什麼究竟VARS(),或特別是,乏()[X] = Y這樣做,

2.什麼範圍這個字典是(我需要記住我寫大程序

3.Whether這是良好的編程 實踐。

在此先感謝!

回答

32

的Python的方式來創建變量

序列如果你想要的變量序列,創建一個序列。而不是試圖建立獨立的變量,例如:

variable0 
variable1 
variable2 
variable3 

你應該看看創建list。這類似於美國洛特是在暗示(美國洛特通常有很好的建議),但地圖更加整齊到你for循環:

sequence = [] 
for _ in xrange(10): 
    sequence.append(function_that_returns_data()) 

(請注意,我們丟棄循環變量(_)我們」重新只是想獲得10次)

那麼你的數據將可爲:

sequence[0] 
sequence[1] 
sequence[2] 
sequence[3] 
[...] 
sequence[9] 

作爲額外的獎勵,你可以這樣做:

for datum in sequence: 
    process_data(datum) 

起初,您可能會抽搐出讓您的序列從0開始。您可以通過各種扭曲來讓您的實際數據從1開始,但它比它的價值更痛苦。我建議僅僅習慣於從零開始的列表。一切都圍繞在他們周圍,他們開始感覺自然很快。

瓦爾()和locals()

現在回答你的問題的另一部分。 vars()(或locals())提供對由python創建的變量的低級訪問。因此以下兩行是等同的。

locals()['x'] = 4 
x = 4 

vars()['x']範圍是完全一樣的x範圍。 locals()(或vars())的一個問題是,它可以讓你把東西放在名字空間中,通過一般的方式你不能離開名字空間。所以你可以做這樣的事情:locals()[4] = 'An integer',但是如果不再使用局部變量,你將無法恢復原狀,因爲局部命名空間(和所有的python命名空間一樣)只能保存字符串。

>>> x = 5 
>>> dir() 
['__builtins__', '__doc__', '__name__', 'x'] 
>>> locals()[4] = 'An integer' 
>>> dir() 
[4, '__builtins__', '__doc__', '__name__', 'x'] 
>>> x 
5 
>>> 4 
4 
>>> locals()[4] 
'An integer' 

請注意,4不會返回與locals()[4]相同的東西。這可能會導致一些意想不到的,難以調試的問題。這是避免使用locals()的原因之一。另一個原因是,爲了完成python提供的更簡單,不易出錯的方法(比如創建一系列變量),通常會遇到很多複雜的事情。

+2

我認爲'vars()['x'] = 4'和'x = 4'實際上只相當於一些時間。如果你在一個函數中這樣做,並且不在其他地方設置'x',並且函數被編譯器優化了,那麼函數後面的'x'的正常查找(即'y = x + 2')沒有工作。我認爲編譯器會緩存它可以看到的變量(可能在編譯時定義),並沒有考慮到這種shenanigan。如果你爲你的函數添加一個exec語句,那麼編譯器不會嘗試優化函數。 – 2010-02-23 21:05:10

+1

感謝周到的答案, 在序列數據: 功能(基準) 看起來非常有用的。今天我學到了很多東西,謝謝! – PPTim 2010-02-23 21:28:38

+0

要查找關於該構造的更多信息,請查找「python迭代器」 – jcdyer 2010-02-23 22:04:09

2

我可以回答3號:這不是很好的編程習慣。我完全不看你想實現什麼,但我相信有這樣做不使用locals()(這是一樣的vars()根據在交互式Python外殼help(vars))的更優雅的方式。

5

從幫助增值經銷商,

瓦爾(...) 瓦爾([對象]) - >詞典

Without arguments, equivalent to locals(). 
With an argument, equivalent to object.__dict__. 

你正在使用它沒有增值經銷商,讓我們看看幫助當地人()

當地人(...) 當地人() - >詞典

Update and return a dictionary containing the current scope's local 

變量。

所以這個回答你的前兩個問題。 vars()將一個字典返回給由變量名稱索引的局部變量作爲字符串。範圍是本地的。

我不知道關於第三個問題,但它似乎是一種黑客攻擊這是不是一個好兆頭的。我想如果你只是在正確的範圍內使用它,你可以隨心所欲地使用它。

+0

我在我的困惑我忘了尋求幫助(),所以趕上了。謝謝, – PPTim 2010-02-23 21:20:59

6

取而代之。這很簡單。

myDict = {} 
for i in range (1,10): 
    temp = "variable"+str(i) 
    myDict[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc. 

這就是你所需要做的。

結果將是myDict['variable1']通過myDict['variable9']

你很少需要vars()locals()。只要停止使用它們並使用普通變量和普通字典即可。儘量避免你不理解的東西,堅持簡單明瞭的東西。

+0

現在我想到了爲什麼我使用了vars(),這可能是因爲在我逐行測試代碼時能夠立即調用變量的感覺很好。感謝你的回答! – PPTim 2010-02-23 21:20:00

1

以這種方式使用變量/本地變量或全局變量是(a)不好的練習和(b)在所有情況下都不起作用。有關更多詳細信息,請參閱Dynamically set local variable。底線:只需使用字典 - 這就是他們的目的。

4

jcdyer非常好地解釋了這些概念,Justin Peel明確指出了vars()locals()的作用。但是一個小例子總能加速理解。

class Bull(object): 

    def __init__(self): 
     self.x = 1 
     self.y = "this" 

    def __repr__(self): 
     return "Bull()" 

    def test1(self): 
     z = 5 
     return vars() 

    def test2(self): 
     y = "that" 
     return vars(self) 

    def test3(self): 
     return locals() 

    def test4(self): 
     y = 1 
     return locals() 

if __name__ == "__main__": 
    b = Bull() 
    print b.test1() 
    print b.test2() 
    print b.test3() 
    print b.test4() 
    print vars(b).get("y") 

導致:

{'self': Bull(), 'z': 5} 
{'y': 'this', 'x': 1} 
{'self': Bull()} 
{'y': 1, 'self': Bull()} 
this 
相關問題