2017-09-13 106 views
0

我有我在做什麼用實例變量的一類,我想用一個類的方法在一個循環中進行修改,簡化版本:實例變量在不修改循環

class Example: 
    def __init__(self,x,z): 
     self.x=x 
     self.z=z 

    def run(self,y): 

     temp_list=[self.x, self.z] 

     for ind,item in enumerate(temp_list): 
      temp_list[ind] = temp_list[ind]+y 

     print (self.x, self.z) 

ex = Example(5,6) 
ex.run(5) 

輸出I得到是[5,6]而不是期望的[10,11]。 我想知道是否有人可以指出我爲什麼發生這種情況的解釋?

+1

從根本上說,你誤會*你正在修改*。您修改列表,而不是列表中的對象。值得一讀的是Ned Batchelder的[關於Python名稱和值的神話和神話](https://nedbatchelder.com/text/names.html) –

+0

請注意,這與實例變量無關。如果您執行'x = 5;您會看到相同的行爲; y = 6; temp_list = [x,y]'然後做同樣的循環。 –

+0

再次感謝您解釋這一點,並感謝您的鏈接,一定會檢查出來。 – Ale

回答

5

run()中,您將創建2個項目的列表,值爲self.xself.z。接下來,您遍歷該列表,並通過向其添加y來修改每個值。 在for -loop之後,temp_list將爲[10, 11],但是您尚未以任何方式修改self.xself.y

因此,print()調用將打印未修改的self.xself.y值,在您的示例中爲5和6。

+0

謝謝!我沒有意識到讓列表創建一個變量的副本......是否有可能以某種方式修改for循環中的實例變量? – Ale

+0

不容易,沒有。 –

+0

根據您的使用情況,您可以在'__init __()'函數中立即將'x'和'z'移動到列表中:'self.x_and_z = [x,z]'。請參閱[其他答案](https://stackoverflow.com/a/46201154/3486486) – Niobos

3

如果你實際上沒有寫self.x = ...,那麼你通常可以假定self.x不會被修改。當您編寫temp_list[ind] + y並將它存儲在temp_list[ind]中時,您將更新列表並帶有一個新值,該值與其他變量碰巧保持的任何值(包括您的對象的變量x)無關。

+0

好吧,我現在明白了差異,謝謝你們解釋這個! – Ale

0

要獲得與你相似的代碼所期望的結果,你可以做這樣的事情:

class Example: 
    def __init__(self,x,z): 
     self.list=[x, z] 
    def run(self,y): 

     for ind,item in enumerate(self.list): 
      self.list[ind] = self.list[ind]+y 

     print (self.list) 

ex = Example(5,6) 
ex.run(5) 

這將在隨後將被用於迭代初始值的初始化定義創建一個self.list項目併爲其添加y值。您遇到的主要錯誤是打印一張未更改過的列表(但您已處於正確的軌道!)

希望這有助於您!

0

您可以使用下面的示例。

class Example: 
    def __init__(self, x, z): 
     self.x = x 
     self.z = z 

    def run(self,y): 
     # Put your init arguments into the array 
     result = [self.x, self.z] 

     # Modify your init arguments 
     for x in range(len(result)): 
      result[x] += y 

     # Return the array with new values 
     return result 

ex = Example(5, 6) 
print(ex.run(5)) 

也許聯繫是對你有所幫助,learn for loop in python