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

Python开发ATM程序如何减少冗余try/except块简化代码

ATM程序重构优化方案

问题背景

现有一款实现了PIN校验、取款功能的ATM程序,业务规则如下:

  • 用户连续3次PIN匹配失败则锁定卡片
  • PIN校验通过后进入取款流程:
    • 输入非数字金额时提示用户重新输入正确值
    • 取款金额大于账户余额时抛出ValueError并退出程序
    • 金额合法则完成扣款出钞
      原代码使用多层嵌套try/except实现异常捕获,结构冗杂可读性差,需要通过减少冗余异常块、拆分功能函数的方式优化代码结构。

原实现代码

user = {
    'pin': 1234,
    'balance': 100
}


def withdraw_cash():
    while True:
        try:
            amount = int(input("Enter the amount of money you want to withdraw: "))
        except ValueError as v:
            print(f"Enter correct amount: ")

        else:
            if amount > user['balance']:
                raise ValueError("You don't have sufficient balance to make this withdrawal")
                is_quit = True

            else:
                user['balance'] = user['balance'] - amount
                print(f"£{amount} successfully withdrawn your remaining balance is £{user['balance']}")
                print('')
                return "Thank you for using Bankomat ATM"

        # finally:
        # print("Program executed")


def bank_atm():
    count = 0
    while count < 3:
        try:
            pin = int(input('Please enter your four digit pin: '))
        except ValueError:
            print("Please enter correct pin")
            count += 1
        else:
            try:
                if pin != user['pin']:
                    print("Pin does not match.. Try Again")
                    count += 1
                else:
                    try:
                        withdraw_cash()
                        return "Thank you for using Bankomat ATM"
                    except ValueError as v:
                        raise v
            except ValueError as v:
                raise v

    if count == 3:
        print('3 UNSUCCESFUL PIN ATTEMPTS, EXITING')
        print('!!!!!YOUR CARD HAS BEEN LOCKED!!!!!')
        is_quit = True
    return "Thank you for using Bankomat ATM"


try:
    bank_atm()
except ValueError as v:
    print(f"ERROR: {v}")

优化思路

原代码的核心问题有三个:

  1. 重复逻辑冗余:PIN输入、取款金额输入都需要做整数合法性校验,两处写了几乎一样的try/except块
  2. 无意义异常中转:多层except ValueError as v: raise v属于完全无效的代码,Python异常会自动向上层调用栈冒泡,不需要手动重抛
  3. 职责混乱+无效代码多:函数嵌套过深,raise语句之后的is_quit = True永远不会执行,还有注释掉的废弃finally块残留

优化后实现

user = {
    'pin': 1234,
    'balance': 100
}

def get_int_input(prompt: str, error_tip: str) -> int:
    """通用整数输入获取,统一处理非数字输入异常"""
    while True:
        try:
            return int(input(prompt))
        except ValueError:
            print(error_tip)

def verify_pin() -> bool:
    """PIN校验逻辑,最多允许3次错误尝试"""
    for remain in range(3, 0, -1):
        pin = get_int_input(
            prompt='请输入4位PIN码:',
            error_tip='请输入合法的数字PIN'
        )
        if pin == user['pin']:
            return True
        print(f'PIN错误,剩余尝试次数:{remain - 1}')
    print('3次PIN校验失败,正在退出')
    print('!!!!!您的卡片已被锁定!!!!!')
    return False

def withdraw_cash() -> None:
    """取款业务逻辑"""
    while True:
        amount = get_int_input(
            prompt='请输入取款金额:',
            error_tip='请输入正确的数字金额'
        )
        if amount > user['balance']:
            raise ValueError("账户余额不足,无法完成取款")
        user['balance'] -= amount
        print(f"成功取款£{amount},剩余余额£{user['balance']}")
        print("感谢使用本行ATM")
        return

def atm_main():
    """ATM流程入口"""
    if not verify_pin():
        return
    withdraw_cash()

if __name__ == "__main__":
    try:
        atm_main()
    except ValueError as e:
        print(f"错误:{e}")

优化效果

  • 代码从原来的3层嵌套try/except变成单层异常捕获,逻辑线性可读,不需要跨层级追踪异常流向
  • 重复的输入校验逻辑统一收敛,后续如果要加输入长度校验、负数校验等规则,只需要改get_int_input一处即可
  • 每个函数职责单一:PIN校验只负责尝试计数和正确性判断,取款逻辑只负责金额校验和扣款,入口只做流程调度,后续迭代功能(比如加查询余额、转账功能)不需要改动现有核心逻辑
  • 所有无效死代码、冗余中转逻辑全部清理,代码可读性大幅提升

内容的提问来源于stack exchange,提问作者Jennifer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:54:23