Как напечатать всю структуру родительский - узел - дочерний - PullRequest
0 голосов
/ 06 июня 2018

Я хочу показать все, что связано с конкретным узлом с помощью функции печати, но пока я не могу избежать использования global для этого.Как я могу сделать свою функцию __repr__ более чистой и более локальной?Весь код, который я получил до сих пор:

current_parent = None
indent_increase = 1


class Node(object):
    def __init__(self, data):
        self.data = data
        self.parent = None
        self.children = []

    def add_child(self, obj):
        self.children.append(obj)
        obj.parent = self.data

    def __repr__(self):
        global current_parent
        global indent_increase

        if self.children:
            print_data = ""
            print_data += "Node " + str(self.data) + " ↴" + "\n"
            indent = "    "

            for child in self.children:
                if current_parent != child.parent:
                    current_parent = child.parent
                    indent_increase += 1
                    print_data += ((indent * indent_increase) + str(child) + "\n")
                else:
                    print_data += ((indent * indent_increase) + str(child) + "\n")

            indent_increase = 1
            current_parent = 0
            return print_data
        else:
            return "Node " + str(self.data)


a = Node(1)
b = Node(2)
c = Node(3)
d = Node(4)
e = Node(5)

c.add_child(d)

a.add_child(b)
a.add_child(c)
a.add_child(e)

print(a)

Желаемый вывод:

Node 1 ↴
    Node 2
    Node 3 ↴
        Node 4
    Node 5

Ответы [ 3 ]

0 голосов
/ 06 июня 2018

Вы можете дать __repr__ больше аргументов со значениями по умолчанию:

class Node(object):
    def __init__(self, data):
        self.data = data
        self.parent = None
        self.children = []

    def add_child(self, obj):
        self.children.append(obj)
        obj.parent = self.data

    def __repr__(self, current_parent=None, indent_increase=1):
        if self.children:
            print_data = ""
            print_data += "Node " + str(self.data) + " ↴" + "\n"
            indent = "    "

            for child in self.children:
                if current_parent != child.parent:
                    print_data += ((indent * indent_increase) + child.__repr__(child.parent, indent_increase + 1) + "\n")
                else:
                    print_data += ((indent * indent_increase) + str(child) + "\n")
            return print_data
        else:
            return "Node " + str(self.data)


a = Node(1)
b = Node(2)
c = Node(3)
d = Node(4)
e = Node(5)

c.add_child(d)

a.add_child(b)
a.add_child(c)
a.add_child(e)

print(a)
0 голосов
/ 06 июня 2018

Простой способ - специальный метод __repr__ делегирует реальную обработку рекурсивному методу.Чтобы избежать беспорядка в интерфейсе, этот метод может иметь имя, начинающееся с подчеркивания (_).Код может быть:

class Node(object):
    def __init__(self, data):
        self.data = data
        self.parent = None
        self.children = []

    def add_child(self, obj):
        self.children.append(obj)
        obj.parent = self.data

    def __repr__(self):
        return self._do_repr(0)

    def _do_repr(self, indent_increase):
        indent = "    "
        print_data = (indent * indent_increase) + "Node " + str(self.data)
        if self.children:
            print_data += " ↴" + "\n"

            for child in self.children:
                print_data += child._do_repr(indent_increase + 1)
        else:
            print_data += '\n'
        return print_data

Это дает, как и ожидалось:

Node 1 ↴
    Node 2
    Node 3 ↴
        Node 4
    Node 5
0 голосов
/ 06 июня 2018

Вы можете работать без globals - вам просто нужно разбить результат от вложенных узлов на строки и сделать отступ каждого из них, прежде чем возвращать результат:

class Node(object):
    def __init__(self, data):
        self.data = data
        self.parent = None
        self.children = []

    def add_child(self, obj):
        self.children.append(obj)
        obj.parent = self

    def __repr__(self):
        if self.children:
            print_data = "Node " + repr(self.data) + " ↴" + "\n"
            indent = "    "
            for child in self.children:
              for line in repr(child).splitlines():
                print_data += indent + line + "\n"
            return print_data
        else:
            return "Node " + repr(self.data)

Я сделал пример с несколькими вложенными узламив https://repl.it/repls/ZanyKlutzyBase

...