Python库转类遇变量未填充错误,求技术指导
Python计算器类转换问题的修正方案
核心问题梳理
你的代码存在多个关键错误,导致PyCharm提示变量未填充、运行时报错:
- 构造函数传参不匹配:创建
Calculator实例时参数数量/类型和__init__定义不符,比如无参实例化、少传参数。 - 魔法方法实现错误:
__add__等运算符重载方法递归调用自身,且签名不符合Python规范,会导致无限递归或参数缺失。 - 方法调用逻辑错误:
IsInRange方法调用时未传参,且验证后的数值未同步到主程序变量;直接通过类调用实例方法,缺少self参数。 - 笔误与逻辑漏洞:
IsInRange2里错误将num2赋值给self.num1,scalc方法里减法/乘法/除法错误使用相同数值计算。
修正后的Calculator类代码
class Calculator: def __init__(self, lr: float, hr: float, num1: float = 0, num2: float = 0, p1: str = ""): # 调整参数顺序,将非必填参数放后面,避免实例化时参数混乱 self.lr = lr self.hr = hr self.num1 = num1 self.num2 = num2 self.p1 = p1 def is_in_range(self, num: float) -> float: # 合并两个范围验证方法,减少冗余代码 while not (self.lr <= num <= self.hr): num = float(input(f"Re-Enter number within your set range {self.lr}, {self.hr}: ")) return num # 修正运算符重载方法的签名与实现,避免递归 def __add__(self): return self.num1 + self.num2 def __sub__(self): return self.num1 - self.num2 def __truediv__(self): try: return self.num1 / self.num2 except ZeroDivisionError: print("Cannot divide by zero.") return None def __mul__(self): return self.num1 * self.num2 def scalc(self, p1: str): a_string = p1.split(",") num1 = float(a_string[0].strip()) num2 = float(a_string[1].strip()) op = a_string[2].strip() # 临时创建实例计算 temp_calc = Calculator(self.lr, self.hr, num1, num2) if op == "+": return temp_calc.__add__() elif op == "-": return temp_calc.__sub__() elif op == "*": return temp_calc.__mul__() elif op == "/": return temp_calc.__truediv__() else: return num1, num2 def all_in_one(self): # 使用当前实例的num1和num2计算 return { 1: self.__add__(), 2: self.__sub__(), 3: self.__mul__(), 4: self.__truediv__() }
类代码修改说明
- 调整
__init__参数顺序,将范围参数设为必填,数值和字符串参数设为可选,简化实例化。 - 合并两个
IsInRange方法为is_in_range,用循环确保输入符合范围,避免重复代码。 - 修正魔法方法:去掉多余参数,直接使用实例的
num1和num2计算,避免无限递归。 - 修复
scalc的逻辑错误,使用临时实例调用计算方法,确保运算符对应正确的数值。 - 重命名方法为蛇形命名(符合Python PEP8规范),提高可读性。
修正后的主程序代码
from Week7_Lib import Calculator print("Welcome to the calculator loop!") print("This calculator's range is: -80, 90") while True: # 获取范围输入 try: lr = int(input('Enter your Lower range: ')) hr = int(input('Enter your Higher range: ')) # 确保范围有效 while hr < lr: print("Higher range must be greater than lower range!") lr = float(input('Re-Enter your Lower range: ')) hr = float(input('Re-Enter your Higher range: ')) print(f"Your range is: {lr},{hr}") except ValueError: print("Please restart the program and enter a valid number for ranges.") exit() # 创建计算器实例 calc = Calculator(lr, hr) # 验证第一个数字 num1 = float(input('Enter first number for validation: ')) num1 = calc.is_in_range(num1) calc.num1 = num1 # 验证第二个数字 num2 = float(input('Enter second number for validation: ')) num2 = calc.is_in_range(num2) calc.num2 = num2 # 菜单选择 print("\nPlease select a function below with the corresponding number.") menu = ["1) Add", "2) Subtract", "3) Multiply", "4) Divide", "5) All In One", "6) Scalc"] for item in menu: print(item) choice = input("\nChoose a function: ") if choice == '1': print(f"The sum of {num1} + {num2} = {calc.__add__()}") elif choice == '2': print(f"The difference of {num1} - {num2} = {calc.__sub__()}") elif choice == '3': print(f"The multiplication of {num1} * {num2} = {calc.__mul__()}") elif choice == '4': result = calc.__truediv__() if result is not None: print(f"The division of {num1} / {num2} = {result}") elif choice == '5': print(f"All functions of this calculator for {num1} and {num2} is: \n{calc.all_in_one()}") elif choice == '6': p1 = input("Please re-enter two numbers and the operator separated by commas (ex 10,20,+): ") print(calc.scalc(p1)) else: print("Unknown choice, please try again.") # 循环选择 loop = input("Do you want to run this program again? Y/N: ").strip().lower() if loop != 'y': print("Thank you for using the calculator.") break
主程序修改说明
- 只创建一个
Calculator实例,复用其范围和数值属性,避免多次实例化的混乱。 - 修复范围验证逻辑,用循环确保高范围大于低范围,替代冗余的条件判断。
- 调用
is_in_range方法后,将返回的有效数值赋值给实例的num1/num2,确保后续计算使用正确值。 - 所有计算方法通过同一个实例调用,避免直接调用类方法导致的参数缺失问题。
- 优化菜单输出和输入处理,提升用户体验。
内容的提问来源于stack exchange,提问作者bob.gillespie
相关产品推荐
相关产品推荐

