Python 中除 Ecception 外的三类系统异常

KeyboardInterrupt、SystemExit、 GeneratorExit

1、python 内置的异常 层次结构

  • 四大系统级异常 (直接继承BaseException)

    python 复制代码
    异常类型	          触发场景	            代码设计建议捕获	            原因
    Exception        所有常规异常的父类        其子类 ✅ 应该	   常规程序错误,应该处理
    KeyboardInterrupt	用户按 Ctrl+C	        ⚠️ 谨慎	           仅用于清理资源,不要完全忽略
    SystemExit	        sys.exit() 调用	        ❌ 不建议	      让程序正常退出,除非有特殊需求
    GeneratorExit	    生成器关闭	            ❌ 不需要	      生成器内部通常不需要处理

2、KeyboardInterrupt 异常捕获

  • 捕获后可以执行清理操作,而不是立即终止程序。
python 复制代码
try:
    print("按Ctrl+C中断程序...")
    while True:
        pass  # 无限循环
except KeyboardInterrupt:
    print("\n捕获到键盘中断!")
    print("可以优雅地清理资源...")

# 用户按Ctrl+C后输出:
# 按Ctrl+C中断程序...
# 捕获到键盘中断!
# 可以优雅地清理资源...

3、SystemExit 异常捕获

  • 捕获后程序不会退出,除非再次raise或调用sys.exit()
python 复制代码
import sys

try:
    print("程序即将退出...")
    sys.exit(42)  # 退出代码42
except SystemExit as e:
    print(f"捕获到SystemExit,退出代码: {e.code}")
    # 可以选择阻止退出
    print("程序继续运行!")

# 输出:
# 程序即将退出...
# 捕获到SystemExit,退出代码: 42
# 程序继续运行!

4、GeneratorExit 异常捕获

  • 当生成器被close()或垃圾回收时,会在生成器内部抛出GeneratorExit。
python 复制代码
def my_generator():
    try:
        print("生成器开始运行")
        for i in range(10):
            yield i
    except GeneratorExit:
        print("生成器被关闭!")
        raise  # 重新抛出,或者选择不抛出

gen = my_generator()
print(next(gen))  # 0
print(next(gen))  # 1
gen.close()       # 关闭生成器

# 输出:
# 生成器开始运行
# 0
# 1
# 生成器被关闭!

5、实际捕获行为对比,一个完整例子展示所有四种:

python 复制代码
import sys
import time

def demo_system_exit():
    try:
        print("\n=== 测试 SystemExit ===")
        sys.exit(100)
    except SystemExit as e:
        print(f"✓ 捕获SystemExit,退出代码: {e.code}")
        print("  程序没有退出,继续执行...")

def demo_keyboard_interrupt():
    try:
        print("\n=== 测试 KeyboardInterrupt ===")
        print("  按Ctrl+C中断...")
        while True:
            time.sleep(0.1)
    except KeyboardInterrupt:
        print("\n✓ 捕获KeyboardInterrupt")
        print("  程序优雅退出...")

def demo_generator_exit():
    print("\n=== 测试 GeneratorExit ===")
    def generator():
        try:
            for i in range(5):
                yield i
        except GeneratorExit:
            print("  ✓ 捕获GeneratorExit")
            raise  # 重新抛出
    
    gen = generator()
    print(f"  生成值: {next(gen)}")
    print(f"  生成值: {next(gen)}")
    gen.close()  # 触发GeneratorExit

def demo_exception():
    try:
        print("\n=== 测试 Exception ===")
        raise ValueError("测试错误")
    except Exception as e:
        print(f"✓ 捕获Exception子类: {type(e).__name__}")
        print(f"  消息: {e}")

# 执行所有测试
demo_system_exit()
demo_generator_exit()
demo_exception()
# demo_keyboard_interrupt()  # 需要手动按Ctrl+C测试
  • 好的实践

    python 复制代码
    # 场景1:处理常规异常
    try:
        data = risky_operation()
    except ValueError as e:
        print(f"参数错误: {e}")
    except (IndexError, KeyError) as e:
        print(f"访问错误: {e}")
    except Exception as e:
        print(f"未知错误: {e}")
        logger.exception("发生异常")
    
    # 场景2:捕获KeyboardInterrupt进行清理
    try:
        main_loop()
    except KeyboardInterrupt:
        print("\n收到中断信号...")
        cleanup_resources()
        print("资源清理完成,退出。")
        sys.exit(0)  # 明确退出    
  • ❌ 不好的实践

    python 复制代码
    # 过度捕获KeyboardInterrupt
    try:
        everything()
    except KeyboardInterrupt:
        print("用户想退出,但我不让他退出!")
        # 继续运行... 这会让用户困惑
    
    # 捕获SystemExit阻止程序退出
    try:
        sys.exit(1)
    except SystemExit:
        print("程序想退出,但我不允许!")
        # 继续运行... 这会破坏退出逻辑
相关推荐
dFObBIMmai8 分钟前
Python Celery任务队列怎么配_实现Web后台异步任务调度处理
jvm·数据库·python
南宫萧幕9 分钟前
Python与Simulink联合仿真:基于DQN的HEV能量管理策略建模与全链路排雷实战
开发语言·人工智能·python·算法·机器学习·matlab·控制
千寻girling15 分钟前
滑动窗口刷了快一个月(26天)了 , 还没有刷完. | 含(操作系统学什么的Java 后端)
java·开发语言·javascript·c++·人工智能·后端·python
WL_Aurora17 分钟前
备战蓝桥杯国赛【day3】
python·蓝桥杯
码农阿豪20 分钟前
Python 操作金仓数据库的完全指南(下篇):SQL执行、批量操作与扩展功能
数据库·python·sql
曲幽23 分钟前
用了loguru我才明白,Python日志还能这么写
python·logging·fastapi·web·async·loguru·handler·uvicorn
小糖学代码24 分钟前
LLM系列:2.pytorch入门:9.神经网络的学习
人工智能·python·深度学习·神经网络·学习·机器学习
曾凡玉@26 分钟前
Python 并发编程系统笔记
开发语言·笔记·python
测试199838 分钟前
接口测试工具:Postman的高级用法
自动化测试·软件测试·python·测试工具·测试用例·接口测试·postman