Python异常处理完全手册(01)

一、什么是异常?

异常的基本概念

异常(Exceptions)是程序在运行过程中出现的意外情况,它会干扰程序的正常执行流程。比如:

  • 尝试打开一个不存在的文件

  • 用0去除一个数

  • 访问不存在的列表元素

  • 把一个字符串转换为整数时字符串不符合数字格式

 
  

# 常见的异常示例print(10 / 0)  # ZeroDivisionError: division by zeronumbers = [1, 2, 3]print(numbers[5])  # IndexError: list index out of rangefile = open("nonexistent.txt")  # FileNotFoundError: [Errno 2] No such file or directory

为什么需要处理异常?

  1. 提升用户体验

    :友好的错误提示比程序崩溃要好

  2. 保证程序健壮性

    :即使出现问题,程序也能继续运行或优雅退出

  3. 资源管理

    :确保文件、网络连接等资源能正确释放

二、异常是怎么引发的?

异常可以通过两种方式引发:

1. Python自动引发

当程序执行到无法继续的情况时,Python会自动抛出异常:

 
  

# 示例1:除零错误def divide(a, b):    return a / bdivide(10, 0)  # Python自动引发ZeroDivisionError# 示例2:类型错误"10" + 10  # Python自动引发TypeError

2. 手动使用raise语句引发

我们可以使用raise关键字主动抛出异常:

 
  

# 示例1:验证输入def validate_age(age):    if age < 0:        raise ValueError("年龄不能为负数")    elif age > 120:        raise ValueError("年龄不合理,请检查输入")# 调用示例try:    validate_age(-5)except ValueError as e:    print(f"输入错误: {e}")

三、异常的处理方法

1. 基本的try-except块

 
  

try:    # 可能引发异常的代码    result = 10 / 0except ZeroDivisionError:    # 处理异常的代码    print("不能除以零!")

2. 处理多种异常

 
  

try:    # 可能有多种异常的代码    number = int(input("请输入一个整数: "))    result = 10 / number    print(f"结果是: {result}")except ValueError:    print("输入的不是有效的整数!")except ZeroDivisionError:    print("不能输入零!")

3. 捕获所有异常

 
  

try:    # 可能有多种异常的代码    file = open("data.txt")    data = file.read()    print(data)except Exception as e:  # 捕获所有异常    print(f"发生错误: {e}")finally:    if 'file' in locals():        file.close()

⚠️ 注意:在实际开发中,应该尽量具体地捕获异常,而不是笼统地捕获Exception

四、finally语句详解

finally的作用

finally语句块定义了一段无论如何都要执行的代码,无论是否发生异常。

为什么需要finally?

  1. 资源清理

    :关闭文件、释放锁、断开网络连接等

  2. 保证执行

    :无论成功还是失败都需要执行的操作

实际案例

 
  

def process_file(filename):    file = None    try:        file = open(filename, 'r')        content = file.read()        # 这里可能有很多处理逻辑        processed = content.upper()        return processed    except FileNotFoundError:        print(f"文件 {filename} 不存在")    except PermissionError:        print(f"没有权限读取文件 {filename}")    except Exception as e:        print(f"处理文件时发生未知错误: {e}")    finally:        if file is not None:  # 确保file存在            file.close()        print("文件处理完成")# 测试result = process_file("example.txt")print(result if result else "")

finally的执行时机

  • 如果没有异常发生:try块 → finally块

  • 如果发生异常被捕获:try块 → except块 → finally块

  • 如果发生异常未被捕获:try块 → finally块 → 抛出异常

五、实战案例:用户输入处理系统

让我们看一个完整的实践案例:

 
  

def get_user_info():    user_data = {}    try:        # 获取姓名        name = input("请输入您的姓名: ")        if not name:            raise ValueError("姓名不能为空")        # 获取年龄        age_input = input("请输入您的年龄: ")        age = int(age_input)        if age < 0 or age > 120:            raise ValueError("年龄必须在0-120之间")        # 获取喜欢的数字        favorite_num_input = input("请输入您最喜欢的数字: ")        favorite_num = float(favorite_num_input)        # 计算结果        score = age * 1.0 / favorite_num        # 构建用户数据        user_data = {            "name": name,            "age": age,            "favorite_num": favorite_num,            "score": score        }    except ValueError as ve:        print(f"输入错误: {ve}")    except ZeroDivisionError:        print("最喜欢的数字不能为零!")    except Exception as e:        print(f"发生未知错误: {e}")    finally:        print("感谢您的参与!")        return user_datadef save_user_data(user_data, filename="user_data.txt"):    try:        with open(filename, 'a') as file:            file.write(str(user_data) + "\n")        print("数据保存成功!")    except IOError as e:        print(f"保存数据时出错: {e}")    except Exception as e:        print(f"发生未知错误: {e}")# 主程序def main():    while True:        user_info = get_user_info()        if user_info:  # 如果有有效数据            save_user_data(user_info)        choice = input("是否继续输入? (y/n): ").lower()        if choice != 'y':            print("程序结束!")            breakif __name__ == "__main__":    main()

在这个案例中,我们实现了:

  1. 处理多种用户输入异常

  2. 使用finally确保始终显示感谢信息

  3. 安全地保存数据到文件

  4. 友好的用户交互体验

六、最佳实践建议

  1. 具体捕获异常

    :不要笼统使用except Exception

  2. 记录异常信息

    :使用logging模块记录完整的错误信息

  3. 清理资源

    :用finally或上下文管理器(with)确保资源释放

  4. 自定义异常

    :为应用特定错误创建自定义异常

  5. 不要静默异常

    :至少记录异常信息,除非有充分理由

 
  

# 自定义异常示例class InvalidPasswordError(Exception):    """密码不符合要求的异常"""    def __init__(self, message="密码必须至少包含8个字符和1个数字"):        self.message = message        super().__init__(self.message)def validate_password(password):    if len(password) < 8 or not any(c.isdigit() for c in password):        raise InvalidPasswordError()try:    validate_password("weak")except InvalidPasswordError as e:    print(f"密码无效: {e}")

你可能感兴趣的:(个人学习,python,开发语言,windows)