Репо: 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 код остается прежним