2017-08-12 51 views
0

所以這裏是我遇到的問題。我正在嘗試迭代makeAThing類,然後使用makeAList類爲迭代創建一個列表。它不是爲makeAThing的每次迭代創建單獨的列表,而是創建一個大的全局列表並向其添加不同的值。有什麼我丟失/還不知道,或者這是如何python的行爲?從類創建python3列表使一個全局列表,而不是一個系列迭代的

class ListMaker(object):  

    def __init__(self,bigList = []): 
     self.bigList = bigList 



class makeAThing(object):  

    def __init__(self,name = 0, aList = []): 
     self.name = name 
     self.aList = aList 

    def makeAList(self): 
     self.aList = ListMaker() 




k = [] 
x = 0 
while x < 3: 
    k.append(makeAThing()) 
    k[x].name = x 
    k[x].makeAList() 
    k[x].aList.bigList.append(x) 
    x += 1  

for e in k: 
    print(e.name, e.aList.bigList) 

output: 

0 [0, 1, 2] 
1 [0, 1, 2] 
2 [0, 1, 2] 


the output I am trying to achieve: 
0 [0] 
1 [1] 
2 [2] 

這之後,我希望能夠編輯的個人名單,並讓他們分配給其迭代

回答

1

init功能使用可變默認參數。從執行 函數定義時從左到右

From the Python documentation:

默認參數值進行了評價。這意味着表達式是 評估一次,定義函數時,並且每個調用使用相同的 「預先計算的」值。尤其是 重要的是要了解何時默認參數是可變對象,例如列表或字典 :如果函數修改對象 (例如通過將項目附加到列表),默認值有效 改性。這通常不是預期的。這 圍繞一個方法是使用無作爲默認,並在體內的功能,例如 明確地測試它:

def whats_on_the_telly(penguin=None): 
    if penguin is None: 
     penguin = [] 
    penguin.append("property of the zoo") 
    return penguin 

在你的代碼,默認參數bigList = []計算一次 - 當函數被定義 - 空列表被創建一次。每次調用該函數時,都會使用相同的列表 - 即使它不再爲空。

默認參數aList = []有同樣的問題,但您立即用makeAList的呼叫覆蓋self.aList,所以不會造成任何問題。

要與您的代碼驗證這一點,請嘗試以下代碼執行後:

print(k[0].aList.bigList is k[1].aList.bigList) 

的對象是一樣的。

有些情況下,這種行爲可能是有用的(憶及Memoization - 雖然有其他更好的方法)。通常,避免可變默認參數。空字符串很好(經常使用),因爲字符串是不可變的。對於列表,字典和排序,您必須在函數中添加一些邏輯。

+0

謝謝!這工作完美! –