如何在函数内无需递归回到起始位置?代码递归问题咨询
class PlayerAttributes: inventory = [] def __init__(self, name, inventory): self.name = name self.inventory = inventory # LIST class Item: def __init__(self, item_name, damage): self.item_name = item_name self.damage = damage class Weapons(Item): weapon_1 = Item("Me Sword", 100) Player_1 = PlayerAttributes("Bob", []) def get_name(): Player_1.name = input("Enter name here: ").capitalize() commands() def stats(): print("Name = " + str(Player_1.name), "\n", "Inventory: ") for x in Player_1.inventory: print(str(x.item_name)) def commands(): prompt = None prompt_choices = {"stats", "quit", "give"} while prompt not in prompt_choices: prompt = input("Enter Command: ").lower() if prompt == "stats": stats() commands() elif prompt == "quit": quit() elif prompt == "give": Player_1.inventory.append(Weapons.weapon_1) commands() get_name()
问题
我目前通过在if语句中调用
commands()回到prompt的while循环,但被告知这属于递归,既不必要还会产生调用栈增长的副作用……
疑问
我应该如何修改代码?
补充问题
调用栈为何会增长?
解答
调用栈增长的原因
每次在stats()执行完成或处理give命令后调用commands(),都会在调用栈中新增一个commands函数的执行帧。比如输入stats,第一个commands函数还没执行完毕(它在等待新调用的commands执行结束),就会形成嵌套调用。每执行一次非quit的命令,调用栈就会多一层,反复执行多次后会触发RecursionError导致程序崩溃。
修改方案:用单循环替代递归
把命令处理逻辑放进一个持续运行的while循环,处理完每个命令后自动回到循环开头等待下一次输入,完全不需要递归调用:
修改后的代码:
class PlayerAttributes: def __init__(self, name, inventory): self.name = name self.inventory = inventory # LIST class Item: def __init__(self, item_name, damage): self.item_name = item_name self.damage = damage class Weapons(Item): weapon_1 = Item("Me Sword", 100) Player_1 = PlayerAttributes("Bob", []) def get_name(): Player_1.name = input("Enter name here: ").capitalize() commands() def stats(): print(f"Name = {Player_1.name}\nInventory: ") for x in Player_1.inventory: print(x.item_name) def commands(): prompt_choices = {"stats", "quit", "give"} # 用外层循环持续接收命令,替代递归 while True: prompt = input("Enter Command: ").lower() if prompt not in prompt_choices: continue if prompt == "stats": stats() elif prompt == "quit": break # 跳出循环结束函数 elif prompt == "give": Player_1.inventory.append(Weapons.weapon_1) get_name()
修改说明
- 将原有的输入验证和命令处理合并到
while True循环中,处理完命令后自动回到循环开头等待新输入。 - 用
break替代quit(),更优雅地退出循环和函数。 - 优化
stats()的打印语句为f-string,代码更简洁。 - 移除
PlayerAttributes中多余的类属性inventory,避免和实例属性混淆。
内容的提问来源于stack exchange,提问作者HardlySalty
相关产品推荐
相关产品推荐

