当前位置: 首页 > article >正文

python教程:python中的异常,异常堆栈及其案例

在 Python 中,异常是程序在运行过程中发生错误的一种处理机制。异常可以中断程序的正常执行,并通过适当的处理来解决错误或提供反馈。如果异常未被处理,程序将会终止并输出一个异常堆栈,显示错误的详细信息。

异常的基本概念

  1. 异常(Exception):在程序执行过程中出现的错误,如除以零、访问不存在的文件等。这些错误会触发一个异常。
  2. 异常处理:通过 try...except 块来捕获和处理异常,防止程序崩溃。
  3. 异常堆栈(Stack Trace):当发生未处理的异常时,Python 会输出异常堆栈,显示从错误发生的地方到程序启动时的函数调用顺序。堆栈有助于调试错误。
  4. 抛出异常:可以通过 raise 语句手动抛出异常。

常见异常类型

  • IndexError:访问列表中不存在的索引时触发。
  • KeyError:访问字典中不存在的键时触发。
  • ValueError:传递无效的参数时触发。
  • ZeroDivisionError:除以零时触发。
  • FileNotFoundError:尝试打开不存在的文件时触发。
  • TypeError:传递不正确的数据类型时触发。

异常处理的基本语法

try:
    # 可能发生异常的代码块
    risky_code()
except SomeException as e:
    # 当发生 SomeException 类型的异常时执行的代码块
    print(f"An error occurred: {e}")
else:
    # 如果没有发生异常,执行的代码块
    print("No exceptions occurred.")
finally:
    # 无论是否发生异常,都会执行的代码块
    print("This code always runs.")
  • try:包含可能会触发异常的代码。
  • except:捕获并处理指定类型的异常,避免程序崩溃。
  • else:当 try 块没有引发异常时执行。
  • finally:无论是否发生异常,都会执行的代码,一般用于资源释放(如关闭文件或网络连接)。

示例:基本的异常处理

try:
    result = 10 / 0  # 这里会触发 ZeroDivisionError
except ZeroDivisionError as e:
    print(f"Caught an exception: {e}")
else:
    print("No exceptions occurred.")
finally:
    print("This will always execute.")

输出:

Caught an exception: division by zero
This will always execute.

捕获多个异常

你可以在 except 块中捕获多个异常类型。如果要捕获多种不同的异常类型,可以通过元组的方式指定。

try:
    value = int("abc")  # 这里会触发 ValueError
except (ValueError, TypeError) as e:
    print(f"An error occurred: {e}")

输出:

An error occurred: invalid literal for int() with base 10: 'abc'

自定义异常

可以通过继承内置的 Exception 类来创建自定义异常,并使用 raise 语句手动抛出异常。

class CustomError(Exception):
    pass

def risky_function(value):
    if value < 0:
        raise CustomError("Negative value is not allowed!")
    return value

try:
    result = risky_function(-10)
except CustomError as e:
    print(f"Caught a custom exception: {e}")

输出:

Caught a custom exception: Negative value is not allowed!

异常堆栈(Stack Trace)

当程序中发生未捕获的异常时,Python 会输出异常堆栈,显示异常发生的位置和调用链,这对于调试非常有帮助。异常堆栈提供了函数调用的详细信息,从错误发生的地方向上追溯到最开始的函数调用。

示例:异常堆栈
def function_c():
    return 1 / 0  # 触发 ZeroDivisionError

def function_b():
    function_c()

def function_a():
    function_b()

# 调用 function_a,最终触发 ZeroDivisionError
function_a()

输出(异常堆栈):

Traceback (most recent call last):
  File "example.py", line 11, in <module>
    function_a()
  File "example.py", line 8, in function_a
    function_b()
  File "example.py", line 5, in function_b
    function_c()
  File "example.py", line 2, in function_c
    return 1 / 0
ZeroDivisionError: division by zero
解释:
  • Traceback:异常堆栈开始部分,显示调用链,从错误发生的地方向上追溯。
  • File "example.py", line 11:显示错误发生的文件、行号和函数。
  • ZeroDivisionError: division by zero:最后一行显示了具体的异常类型和错误信息。

手动抛出异常

你可以使用 raise 语句手动抛出异常。

示例:手动抛出异常
def check_value(value):
    if value < 0:
        raise ValueError("Negative value provided")
    return value

try:
    check_value(-5)
except ValueError as e:
    print(f"Error: {e}")

输出:

Error: Negative value provided
解释:
  • check_value(-5) 被调用时,value 是负数,因此 raise 语句会触发 ValueError 异常,并输出自定义的错误消息。

使用 finally 来确保清理操作

在某些情况下,无论是否发生异常,我们都希望在程序结束时进行某些清理操作,比如关闭文件或数据库连接。这时可以使用 finally 块。

示例:finally
try:
    file = open("example.txt", "r")
    content = file.read()
    print(content)
except FileNotFoundError:
    print("File not found.")
finally:
    file.close()
    print("File closed.")

输出:

File not found.
File closed.
解释:
  • 即使发生 FileNotFoundError 异常,finally 块中的 file.close() 依然会执行,确保资源被正确释放。

捕获异常的最佳实践

  1. 精确捕获异常:尽量捕获特定的异常类型,而不是直接捕获所有异常(如 except Exception:),这样可以避免忽略意料之外的错误。
  2. 适当处理异常:不要只是捕获异常而不做处理,应该记录日志或提供有用的错误信息。
  3. 使用 finally 进行资源管理:确保重要资源(如文件、数据库连接)在程序结束时被正确释放。
  4. 不要滥用异常:异常的处理成本较高,应尽量避免在正常流程中依赖异常控制流程。

总结

  • 异常是程序运行过程中出现的错误,通过 try...except 块来捕获和处理。
  • 异常堆栈是当发生异常时输出的详细信息,帮助开发者定位错误的具体位置。
  • 可以通过 raise 手动抛出异常,通过继承 Exception 类定义自定义异常。
  • finally 块用于无论是否发生异常都要执行的清理操作。

掌握 Python 中的异常处理技巧有助于编写健壮的程序,并且通过异常堆栈能有效地调试和定位错误。


http://www.kler.cn/news/350730.html

相关文章:

  • Python | Leetcode Python题解之第508题出现次数最多的子树元素和
  • vue3中watch的用法以及使用场景以及与watchEffect的使用对比
  • 证件照电子版怎么弄?不花钱制作方法快来学
  • LabVIEW提高开发效率技巧----事件日志记录
  • MySQL查看当前客户端连接数的方法
  • 在xml 中 不等式 做转义处理的问题
  • 【Mysql/xtrabackup】主从恢复(高端操作)
  • 第三课:python学习之安装pygame
  • 安防监控摄像头图传模组,1公里WiFi无线传输方案,监控新科技
  • 如何使用Pillow库在背景图上添加文字的示例代码
  • 学习之高阶编程str方法
  • 路由器接交换机网速会变慢吗
  • JVM篇(Java内存区域与内存溢出异常(深入理解JVM第三版))(持续更新迭代)
  • LabVIEW提高开发效率技巧----图像处理加速
  • C语言 | Leetcode C语言题解之第485题最大连续1的个数
  • 9-单引号和双引号的区别在PHP
  • Python库numpy之三
  • Clip模型详解
  • WebSocket在建立连接时,确实也需要进行TCP的三次握手
  • 【深度学习代码调试1】环境配置篇(上) -- 安装PyTorch(安利方法:移除所有国内源,使用默认源)
  • 大模型量化算法之Smoothquant
  • GCC(GNU Compiler Collection)部分参数解释
  • 网站设计之网站设计总结
  • 深度学习:模型攻击(Model Attack)详解
  • 计算机网络——应用层(DNS域名系统、文件传输协议FTP、远程终端协议TELNET、万维网)
  • 数据库->库的操作