5

可能的重复:
Python 中的“Least Astonishment”:可变默认参数

我创建了一个 Person 类,它有一个名字和一个孩子的列表。孩子们属于同一个 Person 类。如果我创建两个 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>]
4

2 回答 2

10

问题出在children参数的默认值上。如果你使用一个可变对象(例如列表)并在头部初始化它,它只会被初始化一次,然后在所有实例中使用。

此处已对此进行了讨论。

尝试更换

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
于 2013-01-25T13:15:43.487 回答
2

对于您的 init,请改用:

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

发生的情况是两个 Person 对象在后台使用相同的列表(列表在定义函数时绑定,而不是在执行时绑定)。看看这个问题进行更多讨论。

于 2013-01-25T13:16:13.327 回答