Python没有返回相同的对象?

时间:2013-12-15 04:11:39

标签: python

这是我的代码:

class Node:
    nodes = {}

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

        Node.nodes[self.name] = self

    def addParent(self, parent):
        print "adding parent %s for %s " % (parent, self.name)
        self.parent.append(parent)
        print self.parent

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

    def removeParent(self, parent):
        try:
            self.parent.remove(parent)
        except:
            pass

    def removeChild(self, child):
        try:
            self.children.remove(child)
        except:
            pass

def lookup(obj):
    print "calling look up"
    Node.nodes.get(obj)

def create_node(obj):
    return lookup(obj) or Node(obj)

# Tree has Nodes
class Tree:
    trees = {}

    def __init__(self, name, root):
        self.name = name
        self.root = root
        self.size = 1
        self.nodes = set() # tree has unique nodes

        self.nodes.add(root)
        Tree.trees[self.name] = self

    def addNode(self, node):
        self.nodes.add(node)
        self.size += 1

    def removeNode(self, node):
        try:
            self.nodes.remove(node)
        except:
            return
        self.size -= 1

    def setRoot(self, root):
        self.root = root

    def print_tree(self):
        for i in self.nodes:
            if i == self.root.name:
                print "root: %s" % i
            else:
                print i

def main():
    roota = create_node("a")
    ta = Tree("a", roota)

    childaa = create_node("a_a")
    roota.addChild(childaa)
    childaa.addParent(roota)
    ta.addNode(childaa)

    childab = create_node("a_b")
    roota.addChild(childab)
    childab.addParent(roota)
    ta.addNode(childab)


    # make one of the child of a root
    rootb = create_node("a_a")  # should give me a node that already exists from the above tree
    tb = Tree("a_a", rootb)

    childbb = create_node("a_b") # this node should have two parents now, a and a_a
    rootb.addChild(childbb)
    childbb.addParent(rootb)
    tb.addNode(childbb)

    for node in Node.nodes.itervalues():
        print "Name: %s" % node.name
        if node.parent:
            print "Parent: %s" % [parent.name for parent in node.parent]
        else:
            print "Parent: %s" % node.parent
        print "Children: ", [node.name for node in node.children]
        print ""

if __name__ == '__main__':
    main()

脚本的输出:

Name: a  
Parent: []  
Children:  ['a_a', 'a_b']  

Name: a_a  
Parent: []  
Children:  ['a_b']  

Name: a_b  
Parent: ['a_a']  
Children:  []  

a_a应该有父a。第80行正在添加a作为a_a的父级 a_b应该有父a_aa。第85行正在添加a作为a_b

的父级

有人可以向我解释为什么在这段代码中并非如此?

并希望脚本输出:

Name: a  
Parent: []  
Children:  ['a_a', 'a_b']  

Name: a_a  
Parent: ['a']  
Children:  ['a_b']  

Name: a_b  
Parent: ['a', 'a_a']  
Children:  []  

1 个答案:

答案 0 :(得分:1)

树是有向无循环图。树的每个节点本身都是一棵树,因此您不需要树和节点的两个类(除了您想要为您的树提供一些元信息)。

跟踪孩子或父母的情况就足够了,但为方便起见(例如,在两个方向上横穿树),您可以同时保存两者。但是如果你这样做,你必须注意isParent(a,b)与isChild(b,a)同义。在您的代码中,如果您添加节点而不手动设置其父节点,则您的树会变得混乱。

说这个,“#这个节点现在应该有两个父母,a和a_a”如果我们谈论树木就没有多大意义。

基本树结构如下所示(不验证周期):

class Tree:
    def __init__ (self, payload):
        self.payload = payload
        self.children = set ()
        self.parent = None

    def __iadd__ (self, child):
        if child.parent: raise Exception ('Node already attached')
        child.parent = self #update parent
        self.children.add (child) #update children's list
        return self

    def detach (self):
        if not self.parent: return
        self.parent.children.remove (self) #update parent's children's list
        self.parent = None #update self

    def pprint (self, level = 0):
        print (' ' * level + self.payload)
        for child in self.children:
            child.pprint (level + 2)

这是一个例子:

root = Tree ('root')
a = Tree ('A')
b = Tree ('B')
c = Tree ('C')
root += a
root += b
b += c

root.pprint ()
c.detach ()
a += c
root.pprint ()

我希望您能从这个片段中了解如何构建树的一些想法。