Python异常处理

学习时长:2小时 难度:中级 练习:4个

异常处理基础

什么是异常?

异常是程序运行时发生的错误。Python使用异常对象来表示这些错误,并提供了完整的异常处理机制来优雅地处理这些错误。

异常的产生


# 常见的异常情况
print(10 / 0)  # ZeroDivisionError
print(undefined_variable)  # NameError
print(int('abc'))  # ValueError
                

try-except语句

基本语法

try:
    # 可能产生异常的代码
    result = 10 / 0
except ZeroDivisionError as e:
    # 处理特定类型的异常
    print(f"发生除零错误:{e}")
except Exception as e:
    # 处理其他类型的异常
    print(f"发生其他错误:{e}")
else:
    # 没有异常时执行
    print("计算成功")
finally:
    # 无论是否发生异常都会执行
    print("清理工作")
                    
注意事项

不要使用空的except语句捕获所有异常,这可能会掩盖程序中的严重问题。始终指定要捕获的具体异常类型。

常见异常类型

Python内置异常
  • SyntaxError:语法错误
  • NameError:使用未定义的变量
  • TypeError:类型错误
  • ValueError:值错误
  • IndexError:索引超出范围
  • KeyError:字典中不存在的键
  • FileNotFoundError:文件不存在
  • ImportError:导入模块失败

异常层级


try:
    # 尝试打开文件
    with open('不存在的文件.txt') as f:
        content = f.read()
except FileNotFoundError:
    print("文件不存在")
except IOError:
    print("IO错误")
except Exception:
    print("其他错误")
                

自定义异常

当内置异常无法满足需求时,我们可以创建自定义异常类:


class InvalidAgeError(Exception):
    """当年龄值无效时抛出的异常"""
    def __init__(self, age, message="年龄必须在0-150之间"):
        self.age = age
        self.message = message
        super().__init__(self.message)

def verify_age(age):
    if not 0 <= age <= 150:
        raise InvalidAgeError(age)
    return True

# 使用自定义异常
try:
    verify_age(200)
except InvalidAgeError as e:
    print(f"错误:{e}")
                

异常处理最佳实践

推荐做法
  • 只捕获预期的特定异常
  • 在适当的抽象层次处理异常
  • 保持异常处理代码的简洁
  • 利用finally子句进行清理
  • 提供有意义的错误信息

示例:分层异常处理


def read_user_data(filename):
    try:
        with open(filename) as f:
            return json.load(f)
    except FileNotFoundError:
        raise UserDataError(f"用户数据文件 {filename} 不存在")
    except json.JSONDecodeError:
        raise UserDataError("用户数据格式无效")

def process_user(filename):
    try:
        user_data = read_user_data(filename)
        # 处理用户数据
    except UserDataError as e:
        logger.error(f"处理用户数据失败: {e}")
        # 进行适当的错误处理
                

练习与实践

练习1:安全的数值转换器

创建一个函数,可以安全地将字符串转换为整数,处理各种可能的错误情况。

提示:考虑处理ValueError和TypeError异常,对于无效输入返回默认值。

def safe_int_convert(value, default=None):
    """
    安全地将输入值转换为整数
    如果转换失败,返回默认值
    """
    # 在此编写你的代码
    pass
                    

练习2:银行账户管理器

实现一个简单的银行账户类,包含存款和取款方法,使用自定义异常处理各种错误情况。

提示:创建InsufficientFundsError和InvalidAmountError异常类。

class BankAccount:
    def __init__(self, balance=0):
        self.balance = balance

    def deposit(self, amount):
        """存款方法,金额必须为正数"""
        # 在此编写你的代码
        pass

    def withdraw(self, amount):
        """取款方法,金额必须为正数且不能超过余额"""
        # 在此编写你的代码
        pass