'tuple' 对象在我的 Python 代码中没有属性 'position'。我该如何解决?

'tuple' object has no attribute 'position' in my Python code. How can I fix it?

我目前正在 python 中实现 A* 寻路。我一直在关注一个来源并对其进行改编,但我遇到了一个我无法解决的问题。错误涉及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

这里是有问题的 code/function:

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()

如您所见,eq 函数在 Cell class 中似乎没有正常工作,并且没有返回我想要的结果。我试过更改从元组传递到列表的迷宫的起点和终点,但同样的错误仍然存​​在。我该如何修复我的代码?

这是构造函数

class Cell(object):
    def __init__(self, position=None, parent=None):
        self.parent = parent
        self.position = position

这是你使用它的地方

new_cell = Cell(current_cell, cell_position)

看来你把position传给parent,parent传给position了

稍后,这会导致比较 Cell.eq(self.position, other.position) 时出现问题,因为 self.position 实际上是一个单元格,而 other.position 是一个如您所料的原始元组。所以它再次在 self.position 上调用 eq 试图访问 other.position.position (它不存在,因为它是原始元组而不是 Cell 的位置 属性)

您可以使用

修复它
new_cell = Cell(parent=current_cell, position=cell_position)

或者只是将参数按正确的顺序排列。