Python类属性由所有实例共享。如何避免呢?

时间:2020-07-03 16:47:27

标签: python

我有一个Node班。其addAllNodes方法从树中读取项目并将其添加到all_nodes列表中。对于每棵树,我想要一个唯一的all_nodes

d1= [{'id':1,  'name':'one',   'children_id':[2, 3, 4]},
     {'id':2,  'name':'two',   'children_id':[5, 6]},
     {'id':3,  'name':'three', 'children_id':[7]},
     {'id':4,  'name':'four',  'children_id':[8,9]},
     {'id':5,  'name':'five',  'children_id':[]},
     {'id':6,  'name':'six',   'children_id':[10]},
     {'id':7,  'name':'seven', 'children_id':[]},
     {'id':8,  'name':'eight', 'children_id':[11]},
     {'id':9,  'name':'nine',  'children_id':[]},
     {'id':10, 'name':'ten',   'children_id':[]},
     {'id':11, 'name':'eleven',   'children_id':[]} 
]


d2= [{'id':1,  'name':'one',   'children_id':[2, 3]},
     {'id':2,  'name':'two',   'children_id':[5, 6]},
     
]
class Node():

    all_nodes=[]
    
    def __init__(self, d):
        '''d is a dictionary with keys: id, name and children'''
        self.children =[] #list of Nodes
        self.data=d      

    def addNodes(self):            
        for i in self.data['children_id']:
            d=next(item for item in d1 if item['id']==i)
            node=Node(d)
            self.children.append(node)

    def addAllNodes(self):
        
        #if the Node is a leaf
        if not self.data['children_id']:
            self.all_nodes.append(self.data['id'])
            return 
        self.addNodes()
        self.all_nodes.append(self.data['id'])
        for n in self.children:
            n.addAllNodes()
            

  
    
n=Node(d1[0])
n.addAllNodes()
print(n.all_nodes)

k=Node(d2[0])
k.addAllNodes()   
print(k.all_nodes)
print(n.all_nodes)

当我只有一个Node实例时,它会按预期工作。对于2个实例,它会中断并给出一些意外结果,即,比d2中的项目多得多。它的项目甚至比2个预期列表的串联还要多。
我怎么了该代码如何修复?

2 个答案:

答案 0 :(得分:0)

您可能想添加一个单独的Tree类,该类包含all_nodes,并且让Node对其各自的Tree拥有A引用。

答案 1 :(得分:0)

我认为all_nodes不必是类属性。您可以尝试以下方法:

d1 = [
    {"id": 1, "name": "one", "children_id": [2, 3, 4]},
    {"id": 2, "name": "two", "children_id": [5, 6]},
    {"id": 3, "name": "three", "children_id": [7]},
    {"id": 4, "name": "four", "children_id": [8, 9]},
    {"id": 5, "name": "five", "children_id": []},
    {"id": 6, "name": "six", "children_id": [10]},
    {"id": 7, "name": "seven", "children_id": []},
    {"id": 8, "name": "eight", "children_id": [11]},
    {"id": 9, "name": "nine", "children_id": []},
    {"id": 10, "name": "ten", "children_id": []},
    {"id": 11, "name": "eleven", "children_id": []},
]


d2 = [
    {"id": 1, "name": "one", "children_id": [2, 3]},
    {"id": 2, "name": "two", "children_id": [5, 6]},
    {"id": 3, "name": "three", "children_id": []},
    {"id": 5, "name": "five", "children_id": []},
    {"id": 6, "name": "six", "children_id": []},
]


class Node:
    def __init__(self, d, all_data):
        """d is a dictionary with keys: id, name and children."""
        self.children = []  # list of Nodes
        self.data = d
        self.all_nodes = []
        self.all_data = all_data

    def addNodes(self):
        for i in self.data["children_id"]:
            d = next(item for item in self.all_data if item["id"] == i)
            self.children.append(Node(d, self.all_data))

    def addAllNodes(self):
        self.addNodes()
        self.all_nodes.append(self.data["id"])
        for n in self.children:
            self.all_nodes += n.addAllNodes()
        return self.all_nodes


n = Node(d1[0], d1)
n.addAllNodes()
print(n.all_nodes)

k = Node(d2[0], d2)
k.addAllNodes()
print(k.all_nodes)
print(n.all_nodes)

我已经填写了丢失的d2个条目,以免崩溃。