[英]'tuple' object has no attribute 'position' in my Python code. How can I fix it?
I am a currently working on an implementation of A* pathfinding in python.我目前正在致力于在 python 中实现 A* 寻路。 I've been following a source and adapting it, but I am having an issue that I cannot resolve.
我一直在关注一个来源并对其进行调整,但我遇到了一个无法解决的问题。 The error involves pythons eq function, here it is:
错误涉及pythons eq函数,这里是:
Traceback (most recent call last):
File "C:/Users/Patrick/PycharmProjects/untitled/astarmaze.py", line 154, in <module>
main()
File "C:/Users/Patrick/PycharmProjects/untitled/astarmaze.py", line 149, in main
taken_path = a.astarloop()
File "C:/Users/Patrick/PycharmProjects/untitled/astarmaze.py", line 114, in astarloop
if adj == closed_adj:
File "C:/Users/Patrick/PycharmProjects/untitled/astarmaze.py", line 33, in __eq__
return self.position == other.position
File "C:/Users/Patrick/PycharmProjects/untitled/astarmaze.py", line 33, in __eq__
return self.position == other.position
AttributeError: 'list' object has no attribute 'position'
Process finished with exit code 1
and here is the code/function in question:这是有问题的代码/函数:
class Cell(object):
def __init__(self, position=None, parent=None):
self.parent = parent
self.position = position
# our g, h, f variables for f = g + h
self.g = 0
self.h = 0
self.f = 0
def __eq__(self, other):
return self.position == other.position
# def __getitem__(self, index):
# return self.position[index]
#Class for our A* pathfinding, which can take the
class Astar(object):
#initialise the pathfinding and all relevant variables by passing in the maze and its start/end
def __init__(self, maze, start, end, mazeX, mazeY):
# Initialising the open and closed lists for the cells
self.list_open = []
self.list_closed = []
self.maze = maze
self.mazeX = mazeX
self.mazeY = mazeY
self.start_cell = Cell(start, None)
self.start_cell.g = 0
self.start_cell.h = 0
self.start_cell.f = 0
self.end_cell = Cell(end, None)
self.end_cell.g = 0
self.start_cell.h = 0
self.start_cell.f = 0
def astarloop(self):
# adds the starting cell to the open list
self.list_open.append(self.start_cell)
# finding the end cell, loops until found
while len(self.list_open) > 0:
# current cell
current_cell = self.list_open[0]
current_i = 0
for i, item in enumerate(self.list_open):
if item.f < current_cell.f:
current_cell = item
current_i = i
# now it takes the current cell off the open list, and adds it to the closed list, since it has been visited
self.list_open.pop(current_i)
self.list_closed.append(current_cell)
# when the end cell is found, return an array that shows the path taken through the maze to reach the end
if current_cell == self.end_cell:
taken_path = []
current = current_cell
while current is not None:
taken_path.append(current.position)
current = current.parent
return taken_path[::-1] # return the taken path but in reverse
# Generate the children from the current cell, this is important for the algorithm to decide where to go
# based on the 'f' value - it should pick the lowest costed cell to get to the end fastest, adjecent cells to current one
adj_cells = []
for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0), (-1, -1), (-1, 1), (1, -1), (1, 1)]: #adjacent squares in 8 directions
# getting the current cell position
cell_position = (current_cell.position[0] + new_position[0], current_cell.position[1] + new_position[1])
# make sure the cell pos is within the range of the maze array
if cell_position[0] > (len(self.maze) - 1) or cell_position[0] < 0 or cell_position[1] > (len(self.maze[len(self.maze)-1]) - 1) or cell_position[1] < 0:
continue
if self.maze[cell_position[0]][cell_position[1]] != 0:
continue
# new child cell to be appended to adjacent cells
new_cell = Cell(current_cell, cell_position)
adj_cells.append(new_cell)
# time to loop through the adjacent cells
for adj in adj_cells:
for closed_adj in self.list_closed:
if adj == closed_adj:
continue
# create f, g and h for the child adjacent cell
adj.g = current_cell.g + 1
adj.h = ((adj.position[0] - self.end_cell.position[0]) ** 2) + ((adj.position[1] - self.end_cell.position[1]) ** 2)
adj.f = adj.g + adj.h
# already on open list
for open_adj in self.list_open:
if adj == open_adj and adj.g > open_adj.g:
continue
# add to open
self.list_open.append(adj)
def main():
maze = [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
start = (0, 0)
end = (7, 6)
a = Astar(maze, start, end, 0, 0)
taken_path = a.astarloop()
print(taken_path)
if __name__ == "__main__":
main()
As you can see, the eq function doesn't appear to working properly in the Cell class, and is not returning what I would like it to.如您所见, eq函数在 Cell 类中似乎无法正常工作,并且没有返回我想要的结果。 I've tried changing the start and end points of the maze that are passed in from tuples to a list, but the same error persists.
我已经尝试更改从元组传递到列表的迷宫的起点和终点,但同样的错误仍然存在。 How can I fix my code?
如何修复我的代码?
This is the constructor这是构造函数
class Cell(object):
def __init__(self, position=None, parent=None):
self.parent = parent
self.position = position
This is where you use it这是你使用它的地方
new_cell = Cell(current_cell, cell_position)
It looks like you have passed the position as the parent, and the parent as the position.看起来您已将位置作为父级传递,将父级作为位置传递。
Later on, this leads to problems comparing Cell.eq(self.position, other.position) when self.position is actually a cell, but other.position is a raw tuple like you expected.稍后,当 self.position 实际上是一个单元格时,这会导致比较 Cell.eq(self.position, other.position) 的问题,但 other.position 是一个原始元组,就像您预期的那样。 So it calls eq again on self.position which tries to access the other.position.position (which doesn't exist because it's the position property of a raw tuple not of a Cell)
所以它在 self.position 上再次调用 eq ,它试图访问 other.position.position (它不存在,因为它是原始元组的 position 属性而不是 Cell )
You can fix it with你可以用
new_cell = Cell(parent=current_cell, position=cell_position)
or by just putting the arguments in the right order.或者只是将参数按正确的顺序排列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.