Python中如何在while True循环内处理多类用户输入校验错误
邮费计算程序输入校验修复方案
你完全可以在单个while True代码块内统一处理所有输入类的错误校验,不需要为每个输入单独写循环。你当前配送方式校验失效是代码逻辑错误导致的,不是循环结构的问题。
现有代码的错误点
- 配送方式的判断逻辑写错了:你用
shipping_method != ("s", "r", "e", "S", "R", "E")做判断,是拿用户输入的单个字符串和一个元组整体做不等比较,这个判断永远为真,所以无论输入什么内容都会触发错误提示。正确的写法应该是判断输入值是否不在合法选项集合里,要用not in关键字。 - 配送方式的异常捕获是冗余代码:
input()本身返回的就是字符串类型,套一层str()转换永远不会抛出ValueError,这个try-except块根本不会生效。 - 大小写兼容没做全:你把大写S/R/E列为合法输入,但后面计费的分支逻辑只判断小写s/r/e,真输入大写的话会直接报
ship_by变量未定义的错误。 - 物品数量校验有漏洞:只判断了输入等于0的情况,输入负数的话会直接进入计费流程算出错误结果。
单循环统一校验的实现
下面是优化后的完整代码,所有输入校验都放在同一个while True块里,同时简化了计费函数里重复的分支逻辑:
def mail_price_calculator(items, shipping_method): # 统一转小写,兼容大写输入 shipping_method = shipping_method.lower() # 按物品数量算基础单价 unit_cost = 3 if items <= 50 else 2 # 用字典统一存配送规则,不用写重复的if分支 shipping_rule = { "s": (10 if items <= 50 else 0, "Standard post:"), "r": (15 if items <= 50 else 10, "Registered post:"), "e": (20 if items <= 50 else 17, "Express post:") } postage, ship_name = shipping_rule[shipping_method] item_total = items * unit_cost total_fee = item_total + postage print("Receipt: ") print(f"{items} items x ${unit_cost} = ${item_total}") print(f"{ship_name} ${postage}") print(f"Total: ${total_fee}") return total_fee if __name__ == "__main__": items = None shipping_method = None valid_shipping_options = {"s", "r", "e"} while True: # 先校验物品数量 if items is None: try: items = int(input("Enter the number of items: ")) if items <= 0: print("Sorry, number of items must be greater than 0\n") items = None continue except ValueError: print("Sorry, please enter a valid positive integer\n") continue # 数量校验通过后再校验配送方式 if shipping_method is None: user_input = input("Enter shipping method (s/r/e): ").strip().lower() if user_input not in valid_shipping_options: print("Sorry, please enter a valid option: s for standard, r for registered, e for express\n") continue shipping_method = user_input # 两个输入都合法就跳出循环 break print() mail_price_calculator(items, shipping_method)
额外优化说明
- 输入统一做前后空格去除、小写转换,用户不小心输了大写、前后带空格也能正常识别,不用单独列大写选项做判断。
- 用字典存储配送规则,后续要调整邮费、新增配送方式只需要改字典内容,不用加重复的
if-elif分支,维护成本更低。 - 单循环的结构扩展性更好,后续要加新的输入项(比如折扣码、收件地区),只需要在循环里加对应校验段就行,不用额外写新的循环块。
内容的提问来源于stack exchange,提问作者moo moo
相关产品推荐
相关产品推荐

