【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
相关推荐
小白银子4 小时前
零基础从头教学Linux(Day 53)
linux·运维·python
skywalk81634 小时前
基于频域的数字盲水印blind-watermark
linux·开发语言·python
applepie_max4 小时前
GraphRAG本地部署 v2.7.0
python·rag·graphrag
sulikey5 小时前
从零配置一个规范的 Python Git 仓库(适用于 Gitee / GitHub)
git·python·pycharm·gitee·github
shaominjin1235 小时前
android在sd卡中可以mkdir, 但是不可以createNewFile
android·开发语言·python
我是华为OD~HR~栗栗呀5 小时前
华为od-22届考研-测试面经
java·c++·python·功能测试·华为od·华为·面试
学习路上_write6 小时前
神经网络初次学习收获
人工智能·python
大邳草民6 小时前
Django 的动态特性:从 Python 动态机制到框架设计思想
笔记·python·django
用户3721574261356 小时前
Python 裁剪 PDF 教程:轻松裁剪页面并导出为图片
python