Почему узлы класса не сохраняют дочерние элементы вне вызова метода? питон - PullRequest
0 голосов
/ 27 октября 2019

Репо: https://github.com/icarus612/mazeRunner-PY/tree/stack-overflow

Проблема: Я не знаю, почему узлы не сохраняют своих дочерних элементов вне вызова метода runner.

Проект: Я создаю бегун лабиринта с несколькими классами, класс узлов для хранения пятен в лабиринте, класс лабиринта, чтобы брать лабиринты и оценивать, что такое стены и что такое пробелыи класс бегуна для сопоставления лабиринта, поиска возможного маршрута и затем определения маршрута. Существует также решающий скрипт для ввода данных командной строки. Первоначально я построил работающего «бегуна», но он не давал правильный маршрут, поэтому я вернулся к чертежной доске (если кто-то может сказать мне, что бегун не дает правильный маршрут, который тоже был бы крут, но это будетне вопрос под рукой)

Почему узлы не сохраняют там дочерних элементов вне метода?

Код здесь будет сокращенной версией только для того, что является проблемой Imврезаться в это.

Класс узла:

class Node:
    def __init__(self, value):
        self.value = value 
        self.children = []
        self.visited = []

    def add_visited(self, node):
        self.visited.append(node)   

    def add_child(self, child_node):
        self.children.append(child_node) 

    def add_path(self, node_path):
        if not self.path:
            self.path = node_path
        else:
            self.path = self.path if len(self.path) < len(node_path) else node_path

    def remove_child(self, child_node):
        self.children.discard(child_node)

Класс бегуна:

class Runner:
    def __init__(self, maze):
        self.open_nodes = []
        self.visited = []
        self.start = None
        self.end = None
        self.maze = maze
        self.completed = False
        self.mapped_maze = []
        self.node_paths = []
        self.find_end_points()
        self.get_open_nodes()

    def get_open_nodes(self):
        p = self.maze.layout
        for x in range(len(p)):
            for y in range(len(p[x])):
                if p[x][y] != self.maze.wall_char:
                    self.open_nodes.append(Node((x, y)))
        for i in self.open_nodes:
            self.look_around(i)
            print(i.children) #should print something !and does!:)

    def find_end_points(self):
        for x in range(len(self.maze.layout)):
            for y in range(len(self.maze.layout[x])):
                p = self.maze.layout[x][y]
                if p == self.maze.start_char:
                    self.start = Node((x, y))
                elif p == self.maze.end_char:
                    self.end = Node((x, y))

    def look_around(self, node):
        for i in self.open_nodes:
            if i.value[0]-1 == node.value[0] and i.value[1] == node.value[1]:
                node.add_child(i)
            if i.value[0]+1 == node.value[0] and i.value[1] == node.value[1]:
                node.add_child(i)
            if i.value[1]-1 == node.value[1] and i.value[0] == node.value[0]:
                node.add_child(i)
            if i.value[1]+1 == node.value[1] and i.value[0] == node.value[0]:
                node.add_child(i)       

    def make_node_paths(self, point=None):
        if point == None:
            point = self.start
        print(point.value, point.children)
        for i in point.children:
            if i.value not in point.visited:
                point.add_visited(point.value)
                if point.value == self.end.value:
                    self.node_paths.append(point.path)
                    self.completed = True

                self.make_node_paths(i)

Класс лабиринта:

class Maze:
    def __init__ (self, layout=None, start_char="s", end_char="e", wall_char="#", open_char=" ", build=(10, 10)):
        self.wall_char = wall_char
        self.start_char = start_char
        self.end_char = end_char
        self.open_char = open_char
        self.layout = layout
        if layout:
            self.width = len(layout[0])
            self.height = len(layout)
        else:
            self.build_new(build[0], build[1])

Сценарий решателя:

maze = Maze(build=(20, 20)) 

runner = Runner(maze)
print(runner.start.value, runner.start.children) #point that should be logging something !but doesnt!:(
runner.make_node_paths()
complete = "Yes" if runner.completed else "No"
print(f"Is maze possible? {complete}")

Консоль для двух операторов печати:

[<node.Node object at 0x101060780>] #what runner.start.children should be
[<node.Node object at 0x1010604a8>, <node.Node object at 0x100d253c8>]
[<node.Node object at 0x1010604e0>, <node.Node object at 0x1010606d8>]
[<node.Node object at 0x1010604a8>, <node.Node object at 0x100d25400>]
[<node.Node object at 0x100d25470>]
[<node.Node object at 0x1010601d0>, <node.Node object at 0x100d254a8>]
[<node.Node object at 0x1010604e0>, <node.Node object at 0x100d25518>]
[<node.Node object at 0x1010606d8>, <node.Node object at 0x100d25438>, <node.Node object at 0x100d25588>]
[<node.Node object at 0x100d25400>, <node.Node object at 0x100d25470>]
[<node.Node object at 0x101060710>, <node.Node object at 0x100d25438>, <node.Node object at 0x100d255c0>]
[<node.Node object at 0x101060780>, <node.Node object at 0x100d254e0>]
[<node.Node object at 0x100d254a8>, <node.Node object at 0x100d25518>]
[<node.Node object at 0x100d253c8>, <node.Node object at 0x100d254e0>, <node.Node object at 0x100d25550>]
[<node.Node object at 0x100d25518>, <node.Node object at 0x100d25588>]
[<node.Node object at 0x100d25400>, <node.Node object at 0x100d25550>]
[<node.Node object at 0x100d25470>]

(1, 1) [] #runner.start.value and what runner.start.children comes in as

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

Обновление:

Я нашел эту ссылку, которая вроде отвечает на мой вопрос, но не дает ответа: вложенные классы в Python

после прочтения этого мне интересно, нужно ли мне каким-то образом расширять классы друг друга? он дает представление о том, что может происходить, но не дает ответа о том, как я могу исправить свою проблему, и я не работаю с расширенными классами. Я попытался найти способы, чтобы убедиться, что копия является глубокой копией, но даже при использовании copy.deepcopy код остается прежним

1 Ответ

0 голосов
/ 28 октября 2019

Проблема в том, как я сохранял self.start и self.end в функции find_end_points.


    def find_end_points(self):
        def check(node_val):
            if node_val not in [i.value for i in self.open_nodes]:
                node = Node(node_val) 
            else:
                for i in self.open_nodes:
                    if i.value == node_val:
                        node = i
            return node
        for x in range(len(self.maze.layout)):
            for y in range(len(self.maze.layout[x])):
                p = self.maze.layout[x][y]
                if p == self.maze.start_char:
                    self.start = check((x, y))
                elif p == self.maze.end_char:
                    self.end = check((x, y))

- это новая функция, и теперь я получаю правильные начальные и конечные значения, а также дочерние элементы, которые были им сохранены. Это не проблема сохранения глобальных или локальных переменных в методе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...