由于 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')
当我尝试调用属于 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')