所以这就是我遇到的问题。我试图迭代makeAThing类,然后使用makeAList类创建迭代列表。它不是为makeAThing的每次迭代创建单独的列表,而是制作一个大的全局列表并为其添加不同的值。有什么我想念/不知道的,或者这只是python的行为?
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]
之后我希望能够编辑单个列表并将它们分配给它们的迭代
答案 0 :(得分:1)
您的init
函数正在使用可变的默认参数。
From the Python documentation:
默认参数值从左到右进行评估 执行函数定义。这意味着表达式是 在定义函数时评估一次,并且相同 每个呼叫使用“预先计算的”值。这是特别的 当默认参数是可变对象时,重要的是要理解 例如列表或字典:如果函数修改了对象 (例如,通过将项目附加到列表中),默认值有效 改性。这通常不是预期的。解决这个问题的方法 是使用None作为默认值,并在正文中显式测试它 功能,例如:
def whats_on_the_telly(penguin=None):
if penguin is None:
penguin = []
penguin.append("property of the zoo")
return penguin
在您的代码中,默认参数bigList = []
被评估一次 - 当定义函数时 - 创建一个空列表。每次调用该函数时,都会使用相同的列表 - 即使它不再是空的。
默认参数aList = []
存在同样的问题,但您通过调用self.aList
会立即覆盖makeAList
,因此不会导致任何问题。
要使用您的代码验证这一点,请在代码执行后尝试以下操作:
print(k[0].aList.bigList is k[1].aList.bigList)
对象是一样的。
有些情况下这种行为很有用(记住会记住 - 虽然还有其他/更好的方法)。通常,避免使用可变的默认参数。空字符串很好(并经常使用),因为字符串是不可变的。对于列表,字典和排序,您必须在函数内添加一些逻辑。