2013-12-15 151 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() 

我希望你能從這個片段中有關如何採取一些想法建立一棵樹。

相關問題