2017-08-12 74 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

谢谢!这工作完美! –