Python入门(5):异常处理

目录

[1 异常处理基础概念](#1 异常处理基础概念)

[1.1 什么是异常?](#1.1 什么是异常?)

[1.2 异常与错误的区别](#1.2 异常与错误的区别)

[2 异常处理基础](#2 异常处理基础)

[2.1 常见内置异常类型](#2.1 常见内置异常类型)

[2.2 try-except 基本结构](#2.2 try-except 基本结构)

[2.3 捕获多个异常](#2.3 捕获多个异常)

[2.4 抛出异常](#2.4 抛出异常)

[2.4.1 使用raise语句](#2.4.1 使用raise语句)

[2.4.2 自定义异常类](#2.4.2 自定义异常类)

[3 高级异常处理技巧](#3 高级异常处理技巧)

[3.1 不要过度捕获异常](#3.1 不要过度捕获异常)

[3.2 使用上下文管理器(with语句)](#3.2 使用上下文管理器(with语句))

[3.3 记录异常信息](#3.3 记录异常信息)

[3.4 异常链(Exception Chaining)](#3.4 异常链(Exception Chaining))

[3.5 异常处理装饰器](#3.5 异常处理装饰器)


1 异常处理基础概念

1.1 什么是异常?

异常处理是Python编程中至关重要的部分,它帮助我们优雅地处理程序运行时可能出现的错误情况

在Python中,异常 是指程序执行过程中发生的意外情况,它会中断正常的程序流程。当Python遇到无法正常处理的情况时,会**抛出(raise)**一个异常。

python 复制代码
# 基本异常示例
try:
    result = 10 / 0  # 这会引发ZeroDivisionError
except ZeroDivisionError:
    print("不能除以零!")

1.2 异常与错误的区别

  • 语法错误(Syntax Error):代码不符合Python语法规则,程序无法运行

  • 异常(Exception):程序运行时发生的意外情况,可以被捕获和处理


2 异常处理基础

2.1 常见内置异常类型

异常类型 触发场景
SyntaxError 语法错误
IndentationError 缩进错误
NameError 访问未定义变量
TypeError 类型操作不当
ValueError 值无效或不合法
IndexError 序列索引超出范围
KeyError 字典键不存在
AttributeError 对象没有该属性
IOError/OSError 输入/输出操作失败
ImportError 导入模块失败
ZeroDivisionError 除数为零
FileNotFoundError 文件不存在

2.2 try-except 基本结构

python 复制代码
try:
    # 可能引发异常的代码
    result = 10 / 0
except ZeroDivisionError:
    # 处理特定异常
    print("不能除以零!")
except (TypeError, ValueError) as e:
    # 处理多种异常
    print(f"类型或值错误: {e}")
except Exception as e:
    # 捕获所有其他异常
    print(f"发生未知错误: {e}")
else:
    # 没有异常发生时执行
    print("一切正常!")
finally:
    # 无论是否发生异常都会执行
    print("清理工作完成")

2.3 捕获多个异常

python 复制代码
try:
    # 可能引发多种异常的代码
    data = {"key": "value"}
    print(data["missing_key"])  # 可能引发KeyError
    print(10 / 0)              # 可能引发ZeroDivisionError
except (KeyError, ZeroDivisionError) as e:
    print(f"捕获到异常: {type(e).__name__}")

2.4 抛出异常

2.4.1 使用raise语句

python 复制代码
def validate_age(age):
    if age < 0:
        raise ValueError("年龄不能为负数")
    if age > 120:
        raise ValueError("年龄不合理")

try:
    validate_age(-5)
except ValueError as e:
    print(f"验证失败: {e}")

2.4.2 自定义异常类

示例1:

python 复制代码
class InvalidEmailError(Exception):
    """自定义异常类表示无效邮箱"""
    def __init__(self, email, message="无效的邮箱地址"):
        self.email = email
        self.message = message
        super().__init__(f"{message}: {email}")

def send_email(email):
    if "@" not in email:
        raise InvalidEmailError(email)
    
try:
    send_email("invalid.email")
except InvalidEmailError as e:
    print(e)

示例2:

python 复制代码
class MyCustomError(Exception):
    """自定义异常类"""
    def __init__(self, message, code):
        super().__init__(message)
        self.code = code

def validate_age(age):
    if age < 0:
        raise MyCustomError("年龄不能为负数", 400)
    elif age > 120:
        raise MyCustomError("年龄不现实", 400)

try:
    validate_age(-5)
except MyCustomError as e:
    print(f"错误代码 {e.code}: {e}")

3 高级异常处理技巧

3.1 不要过度捕获异常

python 复制代码
# 不好的做法 - 捕获过于宽泛的异常
try:
    do_something()
except:
    pass

# 好的做法 - 只捕获预期的异常
try:
    do_something()
except ExpectedError:
    handle_error()

3.2 使用上下文管理器(with语句)

python 复制代码
# 自动处理资源释放
try:
    with open("data.txt", "r") as f:
        content = f.read()
except IOError as e:
    print(f"文件操作失败: {e}")

3.3 记录异常信息

python 复制代码
import logging
logging.basicConfig(filename="app.log", level=logging.ERROR)

def critical_operation():
    try:
        1 / 0
    except Exception as e:
        logging.exception("操作失败")  # 记录完整堆栈跟踪
        raise  # 重新抛出异常

try:
    critical_operation()
except Exception:
    print("操作失败,请查看日志")

3.4 异常链(Exception Chaining)

python 复制代码
try:
    # 原始异常
    raise ValueError("原始错误")
except ValueError as ve:
    try:
        # 处理时引发新异常
        raise RuntimeError("处理错误") from ve
    except RuntimeError as re:
        print(f"当前异常: {re}")
        print(f"原始异常: {re.__cause__}")

3.5 异常处理装饰器

python 复制代码
from functools import wraps

def handle_errors(logger):
    """异常处理装饰器工厂"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                logger.error(f"{func.__name__} 失败: {e}")
                raise
        return wrapper
    return decorator

# 使用装饰器
import logging
logger = logging.getLogger(__name__)

@handle_errors(logger)
def risky_operation():
    """可能失败的操作"""
    raise ValueError("出错了!")

try:
    risky_operation()
except ValueError:
    print("操作失败已处理")

注意,良好的异常处理策略应该:

  1. 只捕获能处理的异常

  2. 保留原始异常信息

  3. 提供有意义的错误消息

  4. 适当记录错误日志

  5. 在适当的时候重新抛出异常

如果您觉得本文章对您有帮助,别忘了点赞、收藏加关注,更多干货内容将持续发布,您的支持就是作者更新最大的动力。本专栏将持续更新,有任何问题都可以在评论区讨论

相关推荐
我命由我123451 小时前
Spring Boot 自定义日志打印(日志级别、logback-spring.xml 文件、自定义日志打印解读)
java·开发语言·jvm·spring boot·spring·java-ee·logback
蹦蹦跳跳真可爱5892 小时前
Python----计算机视觉处理(Opencv:道路检测之提取车道线)
python·opencv·计算机视觉
徐小黑ACG2 小时前
GO语言 使用protobuf
开发语言·后端·golang·protobuf
0白露3 小时前
Apifox Helper 与 Swagger3 区别
开发语言
Tanecious.4 小时前
机器视觉--python基础语法
开发语言·python
叠叠乐4 小时前
rust Send Sync 以及对象安全和对象不安全
开发语言·安全·rust
ALe要立志成为web糕手4 小时前
SESSION_UPLOAD_PROGRESS 的利用
python·web安全·网络安全·ctf
Tttian6225 小时前
Python办公自动化(3)对Excel的操作
开发语言·python·excel
蹦蹦跳跳真可爱5896 小时前
Python----机器学习(KNN:使用数学方法实现KNN)
人工智能·python·机器学习
独好紫罗兰6 小时前
洛谷题单2-P5713 【深基3.例5】洛谷团队系统-python-流程图重构
开发语言·python·算法