Python3 错误和异常

Python3 错误和异常


🎯 学习目标

掌握 Python 中错误与异常的基本概念、处理机制及自定义异常类的创建方法,能够在实际开发中使用 try...except 结构进行异常捕获和处理,提高程序健壮性。理解异常传播机制,并能结合日志系统记录异常信息。


🔑 核心重点

分类 内容
异常类型 常见内置异常(如 ValueError, TypeError, FileNotFoundError 等)
异常处理结构 使用 try...except...else...finally 捕获并处理异常
自定义异常 继承 Exception 创建自己的异常类
异常传播 函数调用链中的异常传递机制
实际应用场景 文件操作、网络请求、用户输入验证等场景下的异常控制

📚 详细讲解

一、什么是错误和异常?

在 Python 中,错误(Error)异常(Exception) 都是程序运行时中断执行的事件,但它们的用途略有不同:

  • 语法错误(SyntaxError):代码不符合语法规则,无法运行。
  • 运行时错误(Runtime Error):程序运行过程中发生的错误。
  • 异常(Exception):可以被捕获并处理的错误。

✅ 示例:

print(10 / 0)  # 抛出 ZeroDivisionError

输出:

ZeroDivisionError: division by zero

二、常见内置异常类型

异常类型 描述
SyntaxError 语法错误
NameError 变量未定义
TypeError 类型不匹配
ValueError 值不合适(如字符串转整数失败)
IndexError 列表索引超出范围
KeyError 字典键不存在
FileNotFoundError 文件未找到
IOError 输入输出错误
ImportError 导入模块失败
ModuleNotFoundError 模块不存在(Python 3.6+)
KeyboardInterrupt 用户按下 Ctrl+C 终止程序

三、异常处理结构:try...except

✅ 基本结构:

try:
    # 尝试执行的代码
    result = 10 / int(input("请输入除数:"))
except ValueError:
    print("请输入数字!")
except ZeroDivisionError:
    print("除数不能为零!")
else:
    print("结果是:", result)
finally:
    print("无论是否发生异常,都会执行 finally 块")

📌 说明:

  • try:尝试执行可能出错的代码
  • except:捕获指定类型的异常
  • else:没有异常时执行
  • finally:无论是否有异常,都执行(用于清理资源)

四、捕获所有异常(慎用)

try:
    # 一些可能出错的代码
except Exception as e:
    print(f"发生异常:{e}")

📌 不推荐直接使用空 except:,因为它会捕获所有异常,包括 KeyboardInterruptSystemExit


五、手动抛出异常:raise

你可以主动抛出一个异常:

def check_age(age):
    if age < 0:
        raise ValueError("年龄不能为负数!")

check_age(-5)

输出:

ValueError: 年龄不能为负数!

六、自定义异常类

通过继承 Exception 来创建自己的异常类:

class InvalidEmailError(Exception):
    def __init__(self, message="邮箱地址无效"):
        self.message = message
        super().__init__(self.message)

def validate_email(email):
    if "@" not in email:
        raise InvalidEmailError()

validate_email("test.example.com")  # 抛出 InvalidEmailError

七、异常传播机制

当函数内部发生异常而没有被处理时,它会向上传递给调用者,直到最顶层仍未处理,则程序终止。

✅ 示例:

def divide(a, b):
    return a / b

def calculate():
    result = divide(10, 0)
    print(result)

calculate()

输出:

ZeroDivisionError: division by zero

📌 在 divide() 中发生的异常未被捕获,会传播到 calculate(),最终导致程序崩溃。


⚠️ 注意事项

  • 避免“吞异常”行为(即捕获后不做任何处理)
  • 不要盲目使用 except Exception,应明确捕获特定异常
  • finally 块中不要写可能导致新异常的代码
  • 自定义异常应有意义且继承 Exception
  • 处理异常时应考虑资源释放(如关闭文件、断开连接等)

🧪 实际案例分析

📌 场景:构建一个安全的文件读取器

功能需求:

  • 提示用户输入文件名
  • 打开文件并读取内容
  • 若文件不存在或格式错误,提示用户重新输入

示例代码:

while True:
    filename = input("请输入文件名(q退出):")
    if filename.lower() == 'q':
        break
    try:
        with open(filename, 'r', encoding='utf-8') as f:
            content = f.read()
            print(content)
    except FileNotFoundError:
        print("文件未找到,请检查路径是否正确。")
    except UnicodeDecodeError:
        print("文件编码错误,请确认是 UTF-8 编码。")
    except Exception as e:
        print(f"发生未知错误:{e}")

📌 优势:

  • 提高用户体验,避免程序因异常崩溃
  • 支持多类型错误提示
  • 可扩展支持更多异常类型(如权限问题)

🧩 拓展练习(动手实践)

  1. 编写程序,接收两个数字并相除,处理所有可能的异常。
  2. 创建一个自定义异常类 InvalidPasswordError,并在注册逻辑中使用。
  3. 实现一个“文件复制工具”,处理源文件不存在、目标路径无效等异常。
  4. 构建一个命令行菜单系统,处理用户输入错误。
  5. 设计一个“计算器”程序,支持加减乘除,并对非法输入进行完整异常处理。

📚 推荐阅读


🧭 下一步建议

  • 下一章学习内容:《Python3 logging 日志模块》
  • 掌握如何使用 logging 模块记录程序运行状态
  • 学会在异常处理中记录错误日志
  • 学习配置日志级别、输出格式、文件保存等实用技能
  • 构建可维护的日志系统,提升调试效率

如果你希望我为你提供:

  • Python 异常处理速查表 PDF(含异常类型+结构+示例)
  • 更多实战项目练习题(如登录系统异常处理、网络请求重试机制等)
  • 视频教学资源推荐(中文讲解)
  • 如何结合 logging 模块记录异常日志

欢迎随时告诉我 😊

posted @ 2025-06-03 00:02  红尘过客2022  阅读(32)  评论(0)    收藏  举报