今天来记录一题
第六十九题:顶级计算器类
1. 原始版本:把四则运算归拢进一个类
#定义一个简单的计算器,这个类支持加、减、乘、除四种基本运算
#定义计算器类
class Calculate:
"""
定义一个简单的计算器,这个类支持加、减、乘、除四种基本运算
"""
#定义函数
@staticmethod
def add(a,b):
"""
加法
:param a: 加数
:param b: 加数
:return: 和
"""
return a + b
@staticmethod
def subtract(a,b):
"""
减法
:param a: 被减数
:param b: 减数
:return: 差
"""
return a - b
@staticmethod
def multiply(a,b):
"""
乘法
:param a: 乘数
:param b: 乘数
:return: 积
"""
return a * b
@staticmethod
def divide(a,b):
"""
除法
:param a: 被除数
:param b: 除数
:return: 商
"""
if b == 0:
raise ValueError("除数不能为零")
return a / b
#示例使用
calc = Calculate()
a, b = 5, 3
print(f"加法:{a} + {b} = {calc.add(a, b)}")
print(f"减法:{a} - {b} = {calc.subtract(a, b)}")
print(f"乘法:{a} × {b} = {calc.multiply(a, b)}")
print(f"除法:{a} ÷ {b} = {calc.divide(a, b):.2f}")
思路 :加减乘除本身闭着眼都能写,这题真正练的是怎么用面向对象把它们组织起来。四个方法塞进 Calculate 类,参数都是 a 和 b,各返回各的结果。
新面孔是 @staticmethod。之前学生类的方法都带 self,因为它们要读写对象属性。可计算器这四个运算只是"给两个数、还一个结果",压根不碰对象状态,硬塞个 self 进去反而碍眼。挂上 @staticmethod,等于告诉 Python:"这就是个借住在类里的普通函数。"好处是把四个相关运算收进同一个命名空间,调用时 calc.add(a, b) 照样跑。
唯一需要防守的是除法。divide 里先判断 b == 0,是就 raise ValueError 主动拦下。最后写死 a, b = 5, 3 演示一遍。局限还是老样子:数据固定、算完即止。
2. 优化版:让用户自己输、自己选、算完还能续
#定义一个简单的计算器,这个类支持加、减、乘、除四种基本运算
#(优化输入版:用户自主输入数字与运算形式,运算结束后可选择继续)
#定义计算器类
class Calculate:
"""
定义一个简单的计算器,这个类支持加、减、乘、除四种基本运算
"""
#定义函数
@staticmethod
def add(a,b):
"""
加法
:param a: 加数
:param b: 加数
:return: 和
"""
return a + b
@staticmethod
def subtract(a,b):
"""
减法
:param a: 被减数
:param b: 减数
:return: 差
"""
return a - b
@staticmethod
def multiply(a,b):
"""
乘法
:param a: 乘数
:param b: 乘数
:return: 积
"""
return a * b
@staticmethod
def divide(a,b):
"""
除法
:param a: 被除数
:param b: 除数
:return: 商
"""
if b == 0:
raise ValueError("除数不能为零")
return a / b
#辅助函数:读取一个数字(带输入校验)
def read_number(prompt):
"""
反复提示用户输入,直到输入的是一个合法数字为止
:param prompt: 输入提示信息
:return: 转换后的数字(float)
"""
while True:
try:
return float(input(prompt))
except ValueError:
print("输入无效,请输入一个数字。")
#辅助函数:读取一个运算选择(1~4)
def read_choice():
"""
反复提示用户输入,直到选择一个合法的运算编号为止
:return: 运算编号(1、2、3、4)
"""
while True:
choice = input("请选择运算形式(1:加法 2:减法 3:乘法 4:除法):").strip()
if choice in ("1", "2", "3", "4"):
return choice
print("输入无效,请输入 1 ~ 4 之间的数字。")
#主程序
calc = Calculate()
while True:
choice = read_choice()
a = read_number("请输入第一个数字:")
b = read_number("请输入第二个数字:")
#根据用户选择的运算形式调用对应方法并输出结果
if choice == "1":
print(f"加法:{a} + {b} = {calc.add(a, b)}")
elif choice == "2":
print(f"减法:{a} - {b} = {calc.subtract(a, b)}")
elif choice == "3":
print(f"乘法:{a} × {b} = {calc.multiply(a, b)}")
else:
#除法需处理除数为零的异常
try:
print(f"除法:{a} ÷ {b} = {calc.divide(a, b):.2f}")
except ValueError as e:
print(f"计算失败:{e}")
#运算结束后询问用户是否再次进行运算
again = input("是否继续进行运算?(y/n):").strip().lower()
if again != "y":
print("感谢使用,计算器已退出。")
break
思路:计算类一字没动,改的全是"喂输入"这层壳。和前面 68 题优化版一个套路:给能算的芯套一层敢接用户的壳。
加了三个零件。read_number() 用 try 接住 float() 转换,输了字母就提示重来,用 float 而非 int 是为了能算小数。read_choice() 用 if choice in ("1","2","3","4") 做菜单校验,比写一串 or 干净。主循环把一切串起来:先选运算、再读两个数,按编号分发到对应方法。
这里还有个照应原版的细节------只有除法那支额外套了 try/except,接住 divide 抛的"除数为零",正好把上一版埋的防线用上。算完问一句"是否继续",非 y 就 break。
小结:内核还是那个静态方法计算器,升级的全是友好度------数字随便输、运算自己点、除零不崩溃、算完能续用。