咖啡机器程序为何需用exit()而非break/return退出循环?
Python咖啡机器程序的退出逻辑问题
我正在开发一款Python咖啡机器程序,代码如下:
machine = True money = 0 def game(): global money, machine while machine: order = input("What would you like? (espresso/latte/cappuccino) ") # Gets order machine = for_maintainers(order) # if input "off" returns False. if input "report" calls game() recursively printing resources and money. if input anything else returns True. if not machine: exit() #*** if I put here break or return when i type "off" if resources not enough, then program keeps continuing.** * main_menu = sufficient_resources(order) #Returns true if any resource isn't enough. If everything is enough then returns nothing. if main_menu: game() money_inserted = get_money(order) #asks how much quarters, dimes etc. was put. Adds them all and returns that value. money = enough_money(money, money_inserted, order) # Compares price and inserted money. if not enough calls game(), if enough then adds money to resources by returning money. make_coffee(order) #Subtracts from resources coffee, milk, water. game()
程序在资源充足时运行正常,但测试时将资源设为0,输入"latte"会提示资源不足,此时若输入"off"尝试退出循环,使用break或return无法终止程序,仍会继续要求插入硬币;仅使用exit()才能正常退出程序。作为编程新手,恳请解释为何必须使用exit()而非break或return来退出循环。
问题根源:递归调用产生的多层函数栈
核心问题出在你用了递归调用game(),而非break或return本身失效:
- 当资源不足时,
sufficient_resources(order)返回True,触发game()递归调用——相当于新启动了一个game()函数实例在运行。 - 此时输入"off",当前这个新的
game()实例里用break或return,只能退出当前这一层函数,回到上一层game()的执行流程。而上一层函数还停留在if main_menu: game()之后的代码,会继续执行money_inserted = get_money(order),所以会继续要求插入硬币。 exit()是直接终止整个Python解释器进程,不管当前有多少层嵌套的函数调用,都会立刻结束程序,因此能正常退出。
用break/return实现正常退出的两种方案
方案1:移除递归,改用循环内的continue
把递归调用改成continue,让程序回到循环开头重新获取订单,避免产生多层函数栈:
machine = True money = 0 def game(): global money, machine while machine: order = input("What would you like? (espresso/latte/cappuccino) ") machine = for_maintainers(order) if not machine: break # 此时break能直接退出循环,结束函数 main_menu = sufficient_resources(order) if main_menu: continue # 回到循环开头,重新等待用户输入 money_inserted = get_money(order) money = enough_money(money, money_inserted, order) make_coffee(order) game()
方案2:让递归返回状态,控制上层执行
如果一定要保留递归逻辑,让game()返回布尔值表示是否继续执行,上层根据返回值决定是否终止:
machine = True money = 0 def game(): global money, machine while machine: order = input("What would you like? (espresso/latte/cappuccino) ") machine = for_maintainers(order) if not machine: return False # 返回False表示要终止程序 main_menu = sufficient_resources(order) if main_menu: # 递归调用后如果返回False,直接终止当前层 if not game(): return False money_inserted = get_money(order) money = enough_money(money, money_inserted, order) make_coffee(order) return True game()
内容的提问来源于stack exchange,提问作者MaximusPrima
相关产品推荐
相关产品推荐

