page contents

Python异常处理避坑指南,看完少走3年弯路

异常处理用不好,程序崩溃是常事。但过度捕获异常也会掩盖真实问题。今天分享Python异常处理的最佳实践,帮你写出既健壮又易调试的代码!

attachments-2026-05-VxGE4Hdj6a07cc61a955e.png异常处理用不好,程序崩溃是常事。但过度捕获异常也会掩盖真实问题。今天分享Python异常处理的最佳实践,帮你写出既健壮又易调试的代码!

P 1、异常捕获的基本原则——精准捕获,不过度

异常处理的第一原则是:只捕获你知道的异常,不要用裸的except。过度捕获会让bug消失得无影无踪。

❌ 错误示范:裸except捕获一切

try:          
    result = 10 / 0          
except:  # 捕获所有异常,包括KeyboardInterrupt、SystemExit!          
    print('出错了')  # 你根本不知道发生了什么错误

✅ 正确做法:精准捕获具体异常

try:          
    result = 10 / 0          
except ZeroDivisionError:          
    print('除数不能为零')          
except FileNotFoundError:          
    print('文件不存在')          
except Exception as e:          
    print(f'其他错误: {e}')  # 最后兜底,记录真实原因

P 2、异常捕获顺序——从具体到通用

except子句是按顺序匹配的,写在前面的会先被检查。所以一定要把具体异常放在前面,通用异常放在后面!

正确的异常顺序:

try:          
    d = {'x': 1}          
    value = d['y']  # KeyError          
except KeyError:  # 先捕获具体异常          
    print('键不存在')          
except LookupError:  # KeyError和IndexError的父类          
    print('查找失败')          
except Exception:  # 最后兜底          
    print('未知错误')

注意LookupError的子类顺序:

# LookupError hierarchy:          
# - LookupError          
#   - KeyError          
#   - IndexError          
# 所以先捕获KeyError再捕获LookupError是对的

P 3、自定义异常——让错误信息更有意义

内置异常有时候不够描述你的业务场景。自定义异常类,让错误信息更清晰,也方便调用方做针对性处理。

自定义异常的写法:

class ValidationError(Exception):          
    """数据验证失败异常"""          
    def __init__(self, field, message):          
        self.field = field          
        self.message = message          
        super().__init__(f'{field}: {message}')          

class UserNotFoundError(Exception):          
    """用户不存在异常"""          
    pass          

# 使用自定义异常          
def get_user(user_id):          
    if user_id <= 0:          
        raise ValidationError('user_id', '必须为正整数')          
    if user_id not in db:          
        raise UserNotFoundError(f'用户{user_id}不存在')          
    return db[user_id]

P 4、finally子句——资源清理的最佳时机

finally块中的代码无论是否发生异常都会执行,是清理资源(关闭文件、释放锁、关闭连接)的最佳场所。

finally的使用场景:

import sqlite3          

# 场景1:确保文件关闭          
try:          
    f = open('data.txt', 'r')          
    content = f.read()          
except FileNotFoundError:          
    print('文件不存在')          
finally:          
    f.close()# 无论是否出错都关闭文件          

# 场景2:更好的方式是with语句(自动关闭)          
try:          
    with open('data.txt', 'r') as f:          
        content = f.read()          
except FileNotFoundError:          
    print('文件不存在')          
# 文件自动关闭,不需要finally          

# 场景3:确保锁释放          
import threading          
lock = threading.Lock()          
lock.acquire()          
try:          
    # 临界区代码          
    pass          
finally:          
    lock.release()  # 确保锁释放,防止死锁

P 5、总结

今天分享了Python异常处理的核心要点,帮你写出健壮易调试的代码。核心原则:    

1. 精准捕获:用具体异常类型而非裸except,保留关键错误信息          
2. 顺序正确:except子句按书写顺序匹配,具体异常放在前面          
3. 自定义异常:为业务场景定义专门的异常类,让错误处理更清晰          
4. finally必记:无论是否异常都执行,适合资源清理          
5. with语句优先:文件、锁、连接等优先使用with,自动管理资源          
6. 异常要记录:捕获异常后用logging记录完整堆栈,不要只print          
7. 不要过度捕获:只捕获你知道如何处理的异常,不知道的让上层处理          

实践建议:在写except时,多问自己"捕获这个异常后我要做什么?"如果只是pass或简单打印,说明你可能不需要捕获这个异常。好的异常处理不是让错误消失,而是让程序在出错时也能优雅地做出响应,同时留下足够的调试信息。

 更多相关技术内容咨询欢迎前往并持续关注好学星城论坛了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

2059 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 2228 文章
  3. Pack 2059 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章