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("程序想退出,但我不允许!")
        # 继续运行... 这会破坏退出逻辑
相关推荐
独好紫罗兰18 分钟前
对python的再认识-基于数据结构进行-a003-列表-排序
开发语言·数据结构·python
AIFarmer25 分钟前
在EV3上运行Python语言——无线编程
python·ev3
不会代码的小测试27 分钟前
UI自动化-POM封装
开发语言·python·selenium·自动化
2401_8414956429 分钟前
【LeetCode刷题】二叉树的层序遍历
数据结构·python·算法·leetcode·二叉树··队列
ZH154558913139 分钟前
Flutter for OpenHarmony Python学习助手实战:GUI桌面应用开发的实现
python·学习·flutter
B站计算机毕业设计超人1 小时前
计算机毕业设计Hadoop+Spark+Hive招聘推荐系统 招聘大数据分析 大数据毕业设计(源码+文档+PPT+ 讲解)
大数据·hive·hadoop·python·spark·毕业设计·课程设计
B站计算机毕业设计超人1 小时前
计算机毕业设计hadoop+spark+hive交通拥堵预测 交通流量预测 智慧城市交通大数据 交通客流量分析(源码+LW文档+PPT+讲解视频)
大数据·hive·hadoop·python·spark·毕业设计·课程设计
CodeSheep程序羊1 小时前
拼多多春节加班工资曝光,没几个敢给这个数的。
java·c语言·开发语言·c++·python·程序人生·职场和发展
独好紫罗兰1 小时前
对python的再认识-基于数据结构进行-a002-列表-列表推导式
开发语言·数据结构·python
机器学习之心HML1 小时前
多光伏电站功率预测新思路:当GCN遇见LSTM,解锁时空预测密码,python代码
人工智能·python·lstm