【发布时间】:2020-02-22 18:54:38
【问题描述】:
回购: https://github.com/icarus612/mazeRunner-PY/tree/stack-overflow
问题:我不知道为什么节点没有在运行器方法调用之外保存他们的孩子。
项目: 我正在构建一个包含多个类的迷宫跑步者、一个用于在迷宫中存储点的节点类、一个用于进入迷宫并评估什么是墙和什么是空间的迷宫类,以及用于绘制迷宫地图的跑步者类,查找是否有可能的路线,然后求解路线。还有一个求解器脚本可以接受命令行输入。最初我已经建立了一个有效的“跑步者”,但它没有给出正确的路线,所以我回到了绘图板(如果有人能告诉我跑步者没有给出正确的路线,那也很酷,但就是这样不是手头的问题)
为什么节点没有在方法之外保存子节点?
这里的代码将是一个删节版本,只是针对我遇到的问题。
节点类:
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
其他说明: 我没有包含一些运行器类和大多数获取输入的求解器脚本以及大多数构建迷宫的迷宫脚本。我遇到的问题是,当我在初始方法中创建节点并为这些节点的子节点提供保存时,如您所见已注销,但是当我尝试在求解器函数的下一行中将其注销时,我会笨拙地蹲下.我什至不知道我在这里看到的是什么类型的问题。这是记忆还是我保存它们的方式有问题?我试图将它们从集合中切换到数组中,但这也不起作用。如果它全部在同一个方法中,但如果它在 2 个单独的方法中,它似乎工作。就像它退出方法后失去那些孩子一样。
更新:
我发现这个链接回答了我的问题,但没有真正给出答案:nested classes in Python
读完这篇文章后,我想知道我是否需要让这些类以某种方式相互扩展?它提供了对可能发生的事情的洞察,但没有真正回答我如何解决我的问题,而且我不使用扩展类。我已经尝试找到确保副本是深层副本的方法,但即使使用 copy.deepcopy,代码也保持不变
【问题讨论】:
标签: python-3.x class methods graph-algorithm