Новый экземпляр класса наследует предыдущие значения экземпляра - PullRequest
0 голосов
/ 26 октября 2018

Я пишу небольшой класс дерева, который реализует двусвязный список:

class node(object): 
def __init__(self, level=0, pieces=0, parent=None,
             root=None, childNo=None, avgN=2): 

    self.level       = level   # Current level in the tree. Zero = top.
    self.pieces      = pieces  # Number of children. Can be constant or Poisson chosen random.
    self.parent      = parent  # Parent of this node.
    self.child       = {}      # Children of this node. Using a dictionary means
                               # the root could have direct access\
                               # to all children.
    self.childrenID  = {}
    self.myID        = childNo # This node's index in the parents self.child list.

    if (root == None):         # If I'm the root, then hey, I'm the root!
        self.root   = self
    else:
        self.root   = root

    self.avgN          = avgN
    self.numOfChildren = 0
    self.pieces        = self.avgN



def print_all_data(self):
    print "Printing all data for node:",self.myID
    obj_attr = [a for a in dir(n) if not a.startswith('__') and not callable(getattr(n,a))]
    for ob in obj_attr:
        print ob, getattr(n,ob)
    return


# This function acutally adds a child node to this parent.
def add_child_node(self, childno):

    self.numOfChildren        += 1
    if (self.numOfChildren > self.pieces):
        print "Error: number of children exceeds the number of assigned pieces"
        print "       for node:", self.myID

    childno                             = self.compute_new_child_ID(self.level, self.numOfChildren)
    self.childrenID[self.numOfChildren] = childno
    self.child[childno]                 = self.get_new_node(childno)

    return

def get_new_node(self,childno):

    return node(level=self.level+1, parent=self,
                root=self.root, childNo=childno,
                avgN=self.avgN)

def compute_new_child_ID(self, level, childno):
    return (level+1)*100 + childno
def get_child_no_from_child_ID(self, level, childID):
    return childID - (level+1)*100

Обратите внимание, что некоторые функции выглядят дублированными, но они являются заполнителями для будущего использования.

Теперь, если я сделаю экземпляр, я получу:

n = node()
n.print_all_data()

Printing all data for node: None
avgN 2
child {}
childrenID {}
level 0
myID None
numOfChildren 0
parent None
pieces 2
root <__main__.node object at 0x7fb33dc0ae10>

Однако добавление дочерних элементов приводит к тому, что они наследуют свойства родителя:

n.add_child_node(0)
n.add_child_node(1)
n.print_all_data()

Printing all data for node: None
avgN 2
child {101: <__main__.node object at 0x7fb33dc46350>, 102: <__main__.node object at 0x7fb33dc460d0>}
childrenID {1: 101, 2: 102}
level 0
myID None
numOfChildren 2
parent None
pieces 2
root <__main__.node object at 0x7fb33dc0ae10>

Вот дочерние данные:

n.child[101].print_all_data()

Printing all data for node: 101
avgN 2
child {101: <__main__.node object at 0x7fb33dc46350>, 102: <__main__.node object at 0x7fb33dc460d0>}
childrenID {1: 101, 2: 102}
level 0
myID None
numOfChildren 2
parent None
pieces 2
root <__main__.node object at 0x7fb33dc0ae10>

Также создание нового узла наследует эти старые данные экземпляра:

n2 = node()
n2.print_all_data()

Printing all data for node: None
avgN 2
child {101: <__main__.node object at 0x7fb33dc46350>, 102: <__main__.node object at 0x7fb33dc460d0>}
childrenID {1: 101, 2: 102}
level 0
myID None
numOfChildren 2
parent None
pieces 2
root <__main__.node object at 0x7fb33dc0ae10>

Теперь я искал во всем StackOverflow, и я не не смог использовать init (это атрибуты экземпляра) и я неправильно инициализировал неизменный словарь в определении функции (далее объяснено здесь ). Я не смог найти другого примера в SO, который соответствовал бы моей проблеме, отсюда и новый вопрос. Любая помощь с благодарностью.

1 Ответ

0 голосов
/ 26 октября 2018

Экземпляры верны, вы просто печатаете неверные данные.

В методе print_all_data вы всегда печатаете атрибуты экземпляра , на которые ссылается переменная n (которая унаследована от более высокой области видимости и всегда ссылается на ваш "корневой" узел no независимо от того, в каком экземпляре он используется) вместо печати атрибутов текущего экземпляра (self ссылка).

В методе print_all_data вам нужно что-то вроде этого ( на текущий экземпляр ссылается переменная self):

obj_attr = [a for a in dir(self)
            if not a.startswith('__') and not callable(getattr(self, a))]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...