0

在这段代码中:

# coding=utf-8


def print_tree(node, tree=0):
    print(u"|---" * tree + u"-> %s" % node)
    for kid in node.children:
        print_tree(kid, tree + 1)


class Person(object):
    parent = None
    first_name = None
    last_name = None
    children = []

    def __str__(self):
        return '%s %s' % (self.first_name, self.last_name)

    def __unicode__(self):
        return u'%s %s' % (self.first_name, self.last_name)

    def __init__(self, first_name, last_name, parent=None):
        if parent is not None:
            if not isinstance(parent, Person):
                raise AttributeError('`parent` is not `Person` type!')
            self.parent = parent
            self.parent.children.append(self)
        self.first_name = first_name
        self.last_name = last_name
        #self.children = []


root = Person('Alan', 'Smith')
p1 = Person('Barbara', 'Smith', root)
p2 = Person('Basia', 'Smith', root)
p3 = Person('Bary', 'Smith', root)

print_tree(root)

如果我从#self.children = []示例中删除评论效果很好。但我不明白为什么我必须添加这一行?

在调试器中,我发现该行也self.parent.children.append(self)添加selfself.children

为什么 ?

4

4 回答 4

2

children是一个类属性,你希望它是一个实例属性。您应该children=[]完全从类范围中删除,只在__init__方法中保留一个。

于 2013-02-21T15:28:18.260 回答
1

在 python 中,当您在类级别声明一个属性时,这使其成为类属性(在类的所有实例之间共享)。在您的情况下,您需要实例属性。实例属性必须在构造函数(您的self.children = [])中创建。

于 2013-02-21T15:27:54.543 回答
0

您遇到了问题,因为在您的代码children中是 a class variable(当您在类级别而不是实例级别访问它时引用它),而不是instance variable(对于每个实例都是唯一的)。

所以你必须添加类似的东西:

self.children = []

每次你__init__的实例Person

于 2013-02-21T15:27:55.980 回答
0

您正在从对象实例中引用子项,因此您不能仅将其保留在类范围/层中。因此你需要self.children = [],因为否则你指的不是实例的孩子而是类。(后者的语法是Person.children

于 2013-02-21T15:28:04.250 回答