Python将元素添加到实例列表中也会将其添加到另一个实例的列表中

时间:2013-01-25 13:14:13

标签: python class instance-variables

  

可能重复:
  “Least Astonishment” in Python: The Mutable Default Argument

我创建了一个Person类,它有一个名字和一个子列表。孩子们属于同一个人类。如果我创建两个Person实例,并将子项添加到其中一个人员实例,则会将其添加到两个Person实例中。我认为孩子应该只添加到person1的孩子而不是person2,但它会被添加到两者中。我必须做一些明显不对的事,但我看不出来。

类似的问题表明人们将变量定义添加到类本身而不是构造函数,但这不是这里发生的事情。任何帮助都会非常感激,这会让我的脑子油腻!

请参阅下面的代码和输出:

class Person(object):

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

    def __repr__(self):
        return '<' + self.name + '>'

    def add_child(self, child):
        self.children.append(child)


def main():
    person1 = Person('Person1')
    person2 = Person('Person2')

    person1.add_child(Person("Person 1's child"))

    print "Person 1's children:", person1.children
    print "Person 2's children:", person2.children

if __name__ == "__main__":
    main()

此代码的输出是:

Person 1's children: [<Person 1's child>]
Person 2's children: [<Person 1's child>]

2 个答案:

答案 0 :(得分:7)

问题在于children参数的默认值。如果您使用可变对象(例如列表)并在标头中初始化它,它将只初始化一次,然后在所有实例中使用。

已经讨论过here

尝试替换

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

def __init__(self, name, children=None):
    self.name = name
    if children is None:
        self.children = []
    else:
        self.children = children

答案 1 :(得分:1)

对于你的init,请改用:

def __init__(self, name, children=None):
    self.name = name
    if children is None:
        self.children = []
    else:
        self.children = children

正在发生的事情是两个Person对象在后台使用相同的列表(列表在定义函数时绑定,而不是在执行时绑定)。请查看this question以进行更多讨论。