You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

咖啡机器程序为何需用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 20:47:21