由于 AttributeError,无法在列表迭代期间调用对象的 class 函数

Cannot call objects' class function during list iteration due to AttributeError

当我尝试调用属于 Frontier class 的 print_frontier() 时,出现 AttributeError: 'NoneType' object has no attribute 'print_puzzle'print_puzzle() 是 State [=33= 的成员函数] 并在 print_frontier().

内部调用

print_frontier() 需要使用 print_puzzle().

打印每个拼图来打印存储在 self.nodes 中的所有拼图

值得一提的是,当我在主程序中删除frontier.increase_limit()时,代码成功地按预期打印了一个拼图,我担心问题应该在increase_limit()但是我无法弄清楚问题所在。

class Frontier:

    ...


    def increase_limit(self) -> None:
        nodes_to_remove = []
        nodes_to_add = []
        current_nodes = self.nodes.copy()
        self.nodes.clear()

        for node in current_nodes:

            if node is None:
                raise Exception('"node" is a NoneObject')

            empty_tile_pos = node.get_empty_tile_pos()

            if empty_tile_pos not in [0, 1, 2]:
                nodes_to_add.append(
                    State(node.puzzle, node.path).move_tile('up'))
            if empty_tile_pos not in [6, 7, 8]:
                nodes_to_add.append(
                    State(node.puzzle, node.path).move_tile('down'))
            if empty_tile_pos not in [0, 3, 6]:
                nodes_to_add.append(
                    State(node.puzzle, node.path).move_tile('left'))
            if empty_tile_pos not in [2, 5, 8]:
                nodes_to_add.append(
                    State(node.puzzle, node.path).move_tile('right'))

            nodes_to_remove.append(node)

        for node in current_nodes:
            if node not in nodes_to_remove:
                self.nodes.append(node)

        self.nodes.extend(nodes_to_add)
        self.depth += 1

    def print_frontier(self):
        for node in self.nodes:
            node.print_puzzle()  # calling a function of the State class

这里是“状态”class供参考:

class State:

    ...

    def print_puzzle(self):
        print()
        for tile in self.puzzle:
            if self.puzzle.index(tile) in [2, 5, 8]:
                print(tile, end='\n')
            else:
                print(tile, end=' ')
        print(self.path, end='\n')

这是我测试 classes 时的主程序:

start_state = State([0, 2, 4, 5, 7, 6, 8, 3, 1])
frontier = Frontier(start_state)
frontier.increase_limit(). # works well without this line
frontier.print_frontier()

increase_limit 方法中创建一个 State 实例,调用该实例的方法并将该方法的 return 值附加到列表中。

nodes_to_add.append(
    State(node.puzzle, node.path).move_tile('up')
)

为此,move_tile() 需要 return self,这在 python.
中并不常见 如果你不想为State对象使用一个临时变量,你可以这样做:

nodes_to_add.append(State(node.puzzle, node.path))
nodes_to_add[-1].move_tile('up')