Python税务计算器输入校验保留旧值触发运行错误问题咨询
问题根因
你遇到的异常核心是递归调用未返回结果导致的旧输入逻辑回溯执行:
你在get_tax_code函数校验输入失败后,只是直接调用了get_tax_code()重新请求输入,但没有将递归调用的返回值向上传递,这就导致:
- 依次输入32,000(校验失败)、y(校验失败)、1257L(校验成功)时,程序会形成3层调用栈
- 第三层用1257L执行完所有逻辑返回结果后,第二层调用栈不会接收这个结果,而是接着用之前输入的y继续跑后面的逻辑
- 第二层执行完后,第一层调用栈又接着用最早输入的32,000跑后面的逻辑,此时
tax_letter_index还是初始的空字符串,执行切片操作时就触发了类型错误
其他可优化的问题点
tax_letter_index初始值设为空字符串不符合语义,建议改为None,判断逻辑更严谨- 全局变量
gross_income的使用不够规范,建议改为通过参数传递给get_tax_code
修复后的代码
递归方案(最小改动)
def get_tax_code(): tax_code = input('Tax Code: ') print('Tax Code after input:', tax_code) tax_letter_index = None # 校验输入是否包含字母 for char in tax_code: if char.upper() in alpha: tax_letter_index = tax_code.index(char) print('Passed letter check') break if tax_letter_index is None: print('Failed letter check') print('Invalid input. Please enter your tax code.') # 新增return返回递归调用的结果 return get_tax_code() print('Tax Code after letter check:', tax_code) tax_letter = tax_code[tax_letter_index:].upper() # 校验输入是否匹配税务编码字典 if tax_letter not in tax_letters.keys(): print('Tax Code during dictionary match check (false):', tax_code) print('Failed dictionary match check') print('Invalid input. Please enter your tax code.') # 新增return返回递归调用的结果 return get_tax_code() elif tax_letter in tax_letters.keys(): print('Tax Code during dictionary match check (true):', tax_code) print('Passed dictionary match check') print('Tax Code after dictionary match check:', tax_code) # 从税务编码提取个人免税额 personal_allowance = tax_code[:tax_letter_index] if personal_allowance == '': personal_allowance = 0 else: personal_allowance = int(personal_allowance) * 10 # 处理年收入超过10万英镑的免税额调整规则 if gross_income > 100000: personal_allowance = set_personal_allowance - ((gross_income - 100000) / 2) if personal_allowance < 0: personal_allowance = 0 print('Personal Allowance:', personal_allowance) print('Tax Letter:', tax_letter) return personal_allowance, tax_letter
循环方案(更稳定,无调用栈堆积风险)
如果你不想用递归实现重复输入,也可以用无限循环的写法,逻辑更直观:
def get_tax_code(): while True: tax_code = input('Tax Code: ') print('Tax Code after input:', tax_code) tax_letter_index = None # 校验是否包含字母 for char in tax_code: if char.upper() in alpha: tax_letter_index = tax_code.index(char) print('Passed letter check') break if tax_letter_index is None: print('Failed letter check') print('Invalid input. Please enter your tax code.') continue tax_letter = tax_code[tax_letter_index:].upper() # 校验字典匹配 if tax_letter not in tax_letters: print('Tax Code during dictionary match check (false):', tax_code) print('Failed dictionary match check') print('Invalid input. Please enter your tax code.') continue # 全部校验通过后执行后续逻辑 print('Tax Code during dictionary match check (true):', tax_code) print('Passed dictionary match check') print('Tax Code after dictionary match check:', tax_code) # 提取个人免税额 personal_allowance = tax_code[:tax_letter_index] personal_allowance = 0 if personal_allowance == '' else int(personal_allowance)*10 # 调整高收入人群免税额 if gross_income > 100000: personal_allowance = set_personal_allowance - ((gross_income - 100000)/2) personal_allowance = max(personal_allowance, 0) print('Personal Allowance:', personal_allowance) print('Tax Letter:', tax_letter) return personal_allowance, tax_letter
内容的提问来源于stack exchange,提问作者Joshua Ribeiro
相关产品推荐
相关产品推荐

