【Python OOP Diary 1.1】题目二:简单计算器,改错与优化

Python计算器程序优化:从基础到高级的三个版本详解


【Python OOP Diary 1】3个基础题目巩固Class概念

三个版本完整代码

版本一:修正错误的基础版本

python 复制代码
class Calculator:
    def __init__(self, a, b, operator):
        self.a = a
        self.b = b
        self.operator = operator
        self.result = None
        self.valid_operation = True  # 添加标志位控制输出
        
    def calculate(self):
        """执行计算"""
        if self.operator == '+':
            self.result = self.a + self.b
        elif self.operator == '-':
            self.result = self.a - self.b
        elif self.operator == '*':
            self.result = self.a * self.b
        elif self.operator == '/':
            if self.b == 0:
                print('The denominator cannot be zero!')
                self.valid_operation = False
            else:
                self.result = self.a / self.b
        else:
            print('Operator ERROR!')
            self.valid_operation = False
    
    def output(self):
        """输出结果"""
        if self.valid_operation:
            print(f'{self.a}{self.operator}{self.b}={self.result}')

if __name__ == '__main__':
    while True:
        user_input = input().strip().split()
        if user_input == ['0', '0', '0']:
            break
        
        try:
            a, b, operator = float(user_input[0]), float(user_input[1]), user_input[2]
            calculator = Calculator(a, b, operator)
            calculator.calculate()
            calculator.output()
        except (IndexError, ValueError):
            print('Input format ERROR! Please use: number number operator')

版本二:使用异常处理的优化版本

python 复制代码
class Calculator:
    def __init__(self, a, b, operator):
        self.a = a
        self.b = b
        self.operator = operator
        self.result = None
    
    def calculate(self):
        """执行计算并返回结果"""
        operations = {
            '+': lambda: self.a + self.b,
            '-': lambda: self.a - self.b,
            '*': lambda: self.a * self.b,
            '/': lambda: self.a / self.b if self.b != 0 else self._handle_division_by_zero()
        }
        
        if self.operator not in operations:
            raise ValueError('Operator ERROR!')
            
        self.result = operations[self.operator]()
        return self.result
    
    def _handle_division_by_zero(self):
        """处理除零错误"""
        raise ValueError('The denominator cannot be zero!')
    
    def __str__(self):
        """字符串表示,用于输出"""
        if self.result is not None:
            return f'{self.a}{self.operator}{self.b}={self.result}'
        return f'{self.a}{self.operator}{self.b}'

if __name__ == '__main__':
    while True:
        try:
            # 获取输入
            user_input = input().strip().split()
            
            # 退出条件
            if user_input == ['0', '0', '0']:
                break
            
            # 解析输入
            a, b, operator = float(user_input[0]), float(user_input[1]), user_input[2]
            
            # 创建计算器并执行计算
            calculator = Calculator(a, b, operator)
            calculator.calculate()
            
            # 输出结果
            print(calculator)
            
        except ValueError as e:
            # 处理所有错误情况
            print(e)
        except (IndexError, ValueError):
            print('Input format ERROR! Please use: number number operator')

版本三:使用静态方法的进一步优化版本

python 复制代码
class Calculator:
    @staticmethod
    def calculate(a, b, operator):
        """静态方法,直接执行计算"""
        operations = {
            '+': lambda x, y: x + y,
            '-': lambda x, y: x - y,
            '*': lambda x, y: x * y,
            '/': lambda x, y: x / y if y != 0 else exec('raise ValueError("The denominator cannot be zero!")')
        }
        
        if operator not in operations:
            raise ValueError('Operator ERROR!')
            
        return operations[operator](a, b)

if __name__ == '__main__':
    while True:
        try:
            # 获取输入
            user_input = input().strip().split()
            
            # 退出条件
            if user_input == ['0', '0', '0']:
                break
            
            # 解析输入并计算
            a, b, operator = float(user_input[0]), float(user_input[1]), user_input[2]
            result = Calculator.calculate(a, b, operator)
            
            # 输出结果
            print(f'{a}{operator}{b}={result}')
            
        except ValueError as e:
            print(e)
        except (IndexError, ValueError):
            print('Input format ERROR! Please use: number number operator')

七个关键知识点详解

1. self.result = None - 初始化与None值

python 复制代码
def __init__(self, a, b, operator):
    self.a = a
    self.b = b
    self.operator = operator
    self.result = None  # 初始化为None

详解

  • None 是Python中的一个特殊常量,表示"空"或"无值"
  • 使用 None 初始化变量可以明确表示该变量尚未被赋值
  • 与使用0或其他魔法数字相比,None 更能表达"结果待计算"的语义
  • 可以通过 is Noneis not None 来检查变量状态

应用场景

  • 变量初始状态未知
  • 函数返回值可能为空
  • 作为可选参数的默认值

2. Lambda表达式 - 匿名函数

python 复制代码
operations = {
    '+': lambda: self.a + self.b,
    '-': lambda: self.a - self.b,
    '*': lambda: self.a * self.b,
    # ...
}

详解

  • Lambda是创建匿名函数的快捷方式

  • 语法:lambda 参数: 表达式

  • 与普通函数的对比:

    python 复制代码
    # 普通函数
    def add(x, y):
        return x + y
        
    # Lambda表达式
    add = lambda x, y: x + y

特点

  • 单行函数,只能包含一个表达式
  • 自动返回表达式的结果
  • 常用于简单的操作和高阶函数中

3. 条件表达式与函数调用

python 复制代码
'/': lambda: self.a / self.b if self.b != 0 else self._handle_division_by_zero()

详解

  • 这是Python的三元条件运算符

  • 语法:值1 if 条件 else 值2

  • 等价于:

    python 复制代码
    if self.b != 0:
        return self.a / self.b
    else:
        return self._handle_division_by_zero()

优势

  • 代码更简洁
  • 在一行内完成条件判断
  • 提高代码可读性(对于简单条件)

4. 抛出异常 - 主动错误处理

python 复制代码
if self.operator not in operations:
    raise ValueError('Operator ERROR!')

详解

  • raise 语句用于主动抛出异常
  • 可以抛出内置异常或自定义异常
  • 语法:raise 异常类型(错误信息)

常用内置异常

  • ValueError:值错误
  • TypeError:类型错误
  • IndexError:索引错误
  • KeyError:键错误
  • ZeroDivisionError:除零错误

优势

  • 提前发现和处理错误
  • 避免程序继续执行产生更严重的问题
  • 提供清晰的错误信息

5. 异常捕获与处理

python 复制代码
except ValueError as e:
    print(e)

详解

  • try-except 是Python的异常处理机制
  • 可以捕获特定类型的异常
  • as e 将异常对象赋值给变量e,可以访问异常信息

完整语法

python 复制代码
try:
    # 可能抛出异常的代码
    risky_operation()
except SpecificException as e:
    # 处理特定异常
    handle_error(e)
except AnotherException as e:
    # 处理另一种异常
    handle_another_error(e)
else:
    # 如果没有异常发生
    do_something()
finally:
    # 无论是否发生异常都会执行
    cleanup()

6. 多重异常捕获

python 复制代码
except (IndexError, ValueError):
    print('Input format ERROR!')

详解

  • 可以同时捕获多种异常类型
  • 使用元组包含多个异常类型
  • 适用于处理方式相同的多种异常

应用场景

  • 输入验证:多种可能的输入错误
  • 数据解析:多种可能的格式错误
  • API调用:多种可能的网络错误

7. 静态方法详解

python 复制代码
@staticmethod
def calculate(a, b, operator):
    # 不需要self参数
    operations = {
        '+': lambda x, y: x + y,
        '-': lambda x, y: x - y,
        # ...
    }
    return operations[operator](a, b)

静态方法深度解析

1. 基本概念

  • 静态方法使用 @staticmethod 装饰器定义
  • 不需要 self 参数(实例参数)
  • 属于类,但不依赖于类实例

2. 调用方式

python 复制代码
# 通过类名调用(推荐)
result = Calculator.calculate(1, 2, '+')

# 通过实例调用(不推荐)
calc = Calculator(1, 2, '+')  # 实际上不需要创建实例
result = calc.calculate(1, 2, '+')  # 这样调用很奇怪

3. 与实例方法的对比

特性 实例方法 静态方法
参数 需要self参数 不需要self参数
调用 通过实例调用 通过类名调用
访问 可以访问实例属性 不能访问实例属性
用途 操作实例数据 工具函数,与类相关但不依赖实例

4. 与类方法的区别

python 复制代码
class MyClass:
    @staticmethod
    def static_method():
        print("静态方法")
    
    @classmethod
    def class_method(cls):
        print(f"类方法,可以访问类{cls}")
  • 类方法接收 cls 参数,可以访问类属性
  • 静态方法不接收特殊参数,不能访问类或实例属性

5. 静态方法的优势

代码简洁性

python 复制代码
# 实例方法版本
class Calculator:
    def __init__(self, a, b, operator):
        self.a = a
        self.b = b
        self.operator = operator
    
    def calculate(self):
        # 需要访问self.a, self.b, self.operator
        pass

# 使用
calc = Calculator(1, 2, '+')
result = calc.calculate()

# 静态方法版本
class Calculator:
    @staticmethod
    def calculate(a, b, operator):
        # 直接使用参数
        pass

# 使用
result = Calculator.calculate(1, 2, '+')

内存效率

  • 静态方法不需要创建实例,节省内存
  • 对于工具类,可以避免不必要的实例化

设计清晰

  • 明确表示该方法不依赖于对象状态
  • 提高代码的可读性和可维护性

6. 适用场景

  • 工具函数(如数学计算、格式转换)
  • 工厂方法(创建对象)
  • 与类相关但不依赖实例状态的操作

7. 实际应用示例

python 复制代码
class MathUtils:
    @staticmethod
    def factorial(n):
        """计算阶乘"""
        if n == 0:
            return 1
        return n * MathUtils.factorial(n - 1)
    
    @staticmethod
    def is_prime(n):
        """判断素数"""
        if n < 2:
            return False
        for i in range(2, int(n**0.5) + 1):
            if n % i == 0:
                return False
        return True

# 使用
print(MathUtils.factorial(5))  # 120
print(MathUtils.is_prime(17))  # True
相关推荐
38242782717 分钟前
python:正则表达式
前端·python·正则表达式
锐学AI30 分钟前
从零开始学LangChain(二):LangChain的核心组件 - Agents
人工智能·python
风送雨38 分钟前
多模态RAG工程开发教程(上)
python·langchain
棒棒的皮皮41 分钟前
【OpenCV】Python图像处理形态学之膨胀
图像处理·python·opencv·计算机视觉
小草cys44 分钟前
HarmonyOS Next调用高德api获取实时天气,api接口
开发语言·python·arkts·鸿蒙·harmony os
爬山算法44 分钟前
Netty(25)Netty的序列化和反序列化机制是什么?
开发语言·python
未知数Tel1 小时前
Dify离线安装插件
python·阿里云·pip·dify
龘龍龙1 小时前
Python基础学习(六)
开发语言·python·学习
热爱专研AI的学妹1 小时前
【搭建工作流教程】使用数眼智能 API 搭建 AI 智能体工作流教程(含可视化流程图)
大数据·数据库·人工智能·python·ai·语言模型·流程图
databook1 小时前
拒绝“凭感觉”:用回归分析看透数据背后的秘密
python·数据挖掘·数据分析