2013-12-15 109 views
-2

这里是我的代码: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: [] 
+10

请不要使用'except:pass' * ever *。它确实吞下了包括SystemExit和KeyboardInterrupt在内的所有内容。如果你真的想忽略所有的实际*异常*,使用'except Exception:pass'。但即使这是一个糟糕的主意 - “ValueError”就是你需要抓住的所有东西 – ThiefMaster

+0

你试图弄清楚这个bug,你采取了哪些步骤?我们可以通过代码寻找并发现错误,但如果你学会了如何自己找到它,它会更好。 –

+0

@WinstonEwert只是在添加子/父的每一步打印。我看到Node obj的len是三个,所以它似乎在执行查找,所以当a_a被查找时,它应该给我一个已经具有'a'作为父节点的节点,但它并不是我在这里问的。 – ealeon

回答

1

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

跟踪孩子或父母,但为了方便起见(例如在两个方向上横穿树),您可以同时保存两者。但是,如果你这样做,你必须注意的是父母(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() 

我希望你能从这个片段中有关如何采取一些想法建立一棵树。

相关问题