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}")
优化思路
原代码的核心问题有三个:
- 重复逻辑冗余:PIN输入、取款金额输入都需要做整数合法性校验,两处写了几乎一样的try/except块
- 无意义异常中转:多层
except ValueError as v: raise v属于完全无效的代码,Python异常会自动向上层调用栈冒泡,不需要手动重抛 - 职责混乱+无效代码多:函数嵌套过深,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
相关产品推荐
相关产品推荐

