Python 错误处理的最佳实践

 更新时间:2025年08月08日 08:54:59   作者:余子越  
文章系统讲解了Python异常处理机制,涵盖异常定义、常见类型(如ZeroDivisionError、FileNotFoundError等)、try-except结构、else/finally用法、异常抛出与自定义,以及错误处理的最佳实践,帮助开发者有效管理程序运行时错误,感兴趣的朋友一起看看吧

1. 什么是异常?

异常(Exception)就是程序运行时发生的错误,比如试图打开一个不存在的文件、除以零或者输入了非法数据。Python 会抛出异常来告诉你“嘿,这里出问题了!”。如果不处理,程序会直接崩溃,打印一堆错误信息(就是 traceback)。

异常处理的核心是用代码“捕获”这些错误,防止程序崩掉,还能给用户友好的提示。

2. 常见的 Python 异常类型

Python 内置了很多异常类型,了解它们能帮你更好地处理问题。以下是一些常见的异常:

  • ZeroDivisionError:除以零时触发。
  • FileNotFoundError:试图打开不存在的文件。
  • ValueError:函数接收到不合适的参数,比如把字符串传给 int()
  • TypeError:类型错误,比如试图把字符串和整数相加。
  • IndexError:列表索引超出范围。
  • KeyError:访问字典中不存在的键。

这些异常都是 Python 的内置类,继承自 Exception 类。你可以在代码中捕获它们。

3. 基本的 try-except 结构

Python 用 try-except 块来处理异常。基本思路是:把可能出错的代码放进 try 块,如果出错了,就跳到 except 块执行。

来看个简单的例子:

try:
    num = int(input("请输入一个数字: "))
    result = 10 / num
    print(f"10 除以 {num} 等于 {result}")
except:
    print("出错了!可能输入了非法数字或除以零。")

运行这段代码:

  • 如果用户输入一个合法数字,比如 5,程序会打印 10 除以 5 等于 2.0
  • 如果输入了非数字(比如 "abc")或 0,程序会跳到 except 块,打印错误提示,而不会崩溃。

这个 except 是个“通吃”模式,捕获所有异常。但最好别这样用,因为你不知道具体出了啥问题。接下来我们改进它。

4. 捕获特定异常

与其捕获所有异常,不如只捕获你关心的特定异常类型。这样能更精准地处理问题。Python 允许在 except 后指定异常类型。

改写上面的例子:

try:
    num = int(input("请输入一个数字: "))
    result = 10 / num
    print(f"10 除以 {num} 等于 {result}")
except ValueError:
    print("请输入一个合法的数字!")
except ZeroDivisionError:
    print("不能除以零!")

现在:

  • 如果输入 "abc",会触发 ValueError,打印“请输入一个合法的数字!”。
  • 如果输入 0,会触发 ZeroDivisionError,打印“不能除以零!”。
  • 其他异常(比如 KeyboardInterrupt)不会被捕获,程序会照常报错。

你可以捕获多个异常,也可以把异常对象保存下来,查看具体错误信息:

try:
    num = int(input("请输入一个数字: "))
    result = 10 / num
except ValueError as e:
    print(f"输入错误: {e}")
except ZeroDivisionError as e:
    print(f"除零错误: {e}")

这里 as e 把异常对象存到变量 e,可以打印更详细的错误信息。

5. 使用 else 和 finally

try-except 还有两个好用的伙伴:else 和 finally

  • else:如果 try 块没出错,就执行 else 块。适合放那些依赖 try 块成功的代码。
  • finally:不管 try 块有没有出错,finally 块都会执行。常用来做清理工作,比如关闭文件。

来看个例子:

try:
    num = int(input("请输入一个数字: "))
    result = 10 / num
except ValueError:
    print("请输入合法数字!")
except ZeroDivisionError:
    print("不能除以零!")
else:
    print(f"计算成功!结果是: {result}")
finally:
    print("程序结束,清理完成!")

运行效果:

  • 输入 5:打印“计算成功!结果是: 2.0”和“程序结束,清理完成!”。
  • 输入 "abc":打印“请输入合法数字!”和“程序结束,清理完成!”。
  • 输入 0:打印“不能除以零!”和“程序结束,清理完成!”。

finally 特别适合确保资源被正确释放,比如:

try:
    file = open("data.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("文件没找到!")
else:
    print(f"文件内容: {content}")
finally:
    try:
        file.close()
        print("文件已关闭")
    except NameError:
        print("文件从未打开,无需关闭")

这里 finally 确保文件被关闭,即使文件没找到(导致 file 未定义)也能安全处理。

6. 抛出异常

有时候你想主动抛出异常,比如检查到用户输入不符合要求。可以用 raise 关键字抛出异常。

例子:

def divide(a, b):
    if b == 0:
        raise ZeroDivisionError("除数不能为零!")
    return a / b
try:
    result = divide(10, 0)
except ZeroDivisionError as e:
    print(f"错误: {e}")

运行会打印“错误: 除数不能为零!”。你可以用 raise 抛出任何内置异常,或者直接用 raise Exception("自定义消息")

还可以“重新抛出”异常:

try:
    num = int(input("请输入一个数字: "))
except ValueError as e:
    print(f"输入错误: {e}")
    raise  # 重新抛出原异常

这样会在处理完错误后,继续把异常抛给上层调用者。

7. 自定义异常

当内置异常不够用时,你可以定义自己的异常类。自定义异常通常继承自 Exception 类。

例子:

class CustomValueError(Exception):
    """自定义异常,用于值不符合要求"""
    pass
def check_age(age):
    if age < 0 or age > 150:
        raise CustomValueError("年龄必须在0到150之间!")
    return age
try:
    age = check_age(200)
except CustomValueError as e:
    print(f"错误: {e}")

运行会打印“错误: 年龄必须在0到150之间!”。自定义异常让代码更清晰,尤其在复杂项目中。

8. 错误处理的最佳实践

最后,分享一些写错误处理代码的建议:

  • 捕获特定异常:别用“通吃”的 except,尽量指定具体的异常类型。
  • 提供清晰的错误信息:用户看到错误时,应该知道问题出在哪,怎么解决。
  • 用 else 和 finally 合理组织代码else 放依赖 try 成功的逻辑,finally 放清理工作。
  • 别滥用异常:异常是用来处理“异常情况”的,别用它来控制正常流程(比如代替 if 判断)。
  • 记录错误日志:在实际项目中,用 logging 模块记录异常,方便调试。

例子(带日志):

import logging
logging.basicConfig(level=logging.ERROR, filename="app.log")
try:
    num = int(input("请输入一个数字: "))
    result = 10 / num
except ValueError as e:
    logging.error(f"输入错误: {e}")
    print("请输入合法数字!")
except ZeroDivisionError as e:
    logging.error(f"除零错误: {e}")
    print("不能除以零!")
else:
    print(f"结果: {result}")
finally:
    print("程序结束!")

这个例子会把错误记录到 app.log 文件,方便排查问题。

到此这篇关于Python 错误处理详解的文章就介绍到这了,更多相关Python 错误处理详解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python3.7.0的安装步骤

    python3.7.0的安装步骤

    本文分步骤给大家介绍了python3.7.0的安装步骤,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-08-08
  • 执行Django数据迁移时报 1091错误及解决方法

    执行Django数据迁移时报 1091错误及解决方法

    这篇文章主要介绍了执行Django数据迁移,报错 1091,需要的朋友可以参考下
    2019-10-10
  • Selenium获取登录Cookies并添加Cookies自动登录的方法

    Selenium获取登录Cookies并添加Cookies自动登录的方法

    这篇文章主要介绍了Selenium获取登录Cookies并添加Cookies自动登录的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Python简单获取网卡名称及其IP地址的方法【基于psutil模块】

    Python简单获取网卡名称及其IP地址的方法【基于psutil模块】

    这篇文章主要介绍了Python简单获取网卡名称及其IP地址的方法,结合实例形式分析了Python基于psutil模块针对本机网卡硬件信息的读取操作简单使用技巧,需要的朋友可以参考下
    2018-05-05
  • 在Python中预先初始化列表内容和长度的实现

    在Python中预先初始化列表内容和长度的实现

    今天小编就为大家分享一篇在Python中预先初始化列表内容和长度的实现,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • 修改Python的pyxmpp2中的主循环使其提高性能

    修改Python的pyxmpp2中的主循环使其提高性能

    这篇文章主要介绍了修改Python的pyxmpp2中的主循环使其提高性能,pyxmpp2是Python中使用需XMPP协议的一个常用工具,要的朋友可以参考下
    2015-04-04
  • 跟老齐学Python之开始真正编程

    跟老齐学Python之开始真正编程

    通过对四则运算的学习,已经初步接触了Python中内容,但是到目前为止,还不能算编程,只能算会用一些指令(或者叫做命令)来做点简单的工作。列位稍安勿躁,下面我们就学习如何编写一个真正的程序。
    2014-09-09
  • Python matplotlib画曲线例题解析

    Python matplotlib画曲线例题解析

    这篇文章主要介绍了Python matplotlib画曲线例题解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Python 编码规范(Google Python Style Guide)

    Python 编码规范(Google Python Style Guide)

    本项目并非 Google 官方项目, 而是由国内程序员凭热情创建和维护,对于想学习python的朋友可以参考一下
    2018-05-05
  • Python使用pytorch动手实现LSTM模块

    Python使用pytorch动手实现LSTM模块

    这篇文章主要介绍了Python使用pytorch动手实现LSTM模块,LSTM是RNN中一个较为流行的网络模块。主要包括输入,输入门,输出门,遗忘门,激活函数,全连接层(Cell)和输出
    2022-07-07

最新评论