python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python异常类型使用

Python异常类型的使用及说明

作者:Tipriest_

Python异常类型丰富且层次分明,涵盖运行时错误、设计意图异常、外部交互错误等,合理使用内置异常及自定义异常能提升代码健壮性与可维护性

在Python中,我们可以 raise 的 Error(更准确地说是 Exception,异常)类型非常丰富,它们构成了一个清晰的类层次结构。了解这些类型及其用途,对于编写健壮、可读性强的代码至关重要。

NotImplementedError 是一个非常好的例子,它代表了一种特定的“设计意图”,而不仅仅是运行时错误。

下面我将为您详细介绍Python中可以 raise 的主要异常类型,并按照它们的逻辑关系和用途进行分类。

一、异常的基本层次结构

所有Python的内置异常都继承自 BaseException 类。这个层次结构非常重要:

BaseException
 ├── SystemExit
 ├── KeyboardInterrupt
 └── Exception  <-- 绝大多数异常都继承自这里
      ├── StopIteration
      ├── ArithmeticError
      │    ├── ZeroDivisionError
      │    └── OverflowError
      ├── AssertionError
      ├── AttributeError
      ├── ImportError
      │    └── ModuleNotFoundError
      ├── LookupError
      │    ├── IndexError
      │    └── KeyError
      ├── NameError
      ├── OSError
      │    ├── FileNotFoundError
      │    └── PermissionError
      ├── RuntimeError
      │    └── NotImplementedError  <-- 你提到的在这里
      ├── TypeError
      ├── ValueError
      └── ...等等

一条黄金法则:

在你的 try...except 语句中,通常应该捕获 Exception 或其子类,而不是 BaseException。因为 SystemExitKeyboardInterrupt 不被认为是程序“错误”,捕获它们会阻止程序正常退出或响应用户中断(Ctrl+C)。

二、主要异常类型详解

我将它们分为几类,以便更好地理解它们的用途。

类别1:最常见的运行时错误

这些是你在日常编程中遇到最多的错误。

ValueError

TypeError

NameError

IndexError

KeyError

AttributeError

类别2:用于程序设计和逻辑控制的异常

这类异常通常由程序员主动 raise,以表明某种设计上的约定或状态。

NotImplementedError (继承自 RuntimeError)

示例

class Shape:
    def get_area(self):
        # 任何继承自Shape的子类都必须实现自己的get_area方法
        raise NotImplementedError("Subclasses must implement this method!")

class Square(Shape):
    def __init__(self, side):
        self.side = side
    
    # 如果不写下面的方法,调用 get_area() 就会报错
    def get_area(self):
        return self.side ** 2

# s = Shape()
# s.get_area()  # 这会立即引发 NotImplementedError
sq = Square(5)
print(sq.get_area()) # 输出 25

AssertionError

示例

def process_data(data):
    assert isinstance(data, list), "Input data must be a list"
    # ... 后续处理 ...

process_data("not a list") # 引发 AssertionError: Input data must be a list

RuntimeError

类别3:与外部环境交互的错误

OSError

它的重要子类包括

类别4:算术和导入错误

ArithmeticError

子类包括

ImportError

类别5:语法错误(特殊情况)

SyntaxError

三、创建你自己的自定义异常

当内置的异常类型无法精确描述你的应用程序特有的错误时,最佳实践是创建自己的异常类。这能让你的代码更具可读性和可维护性。

自定义异常应该继承自 Exception 或其某个合适的子类。

示例:假设你在开发一个与外部API交互的应用。

# 1. 创建一个基础的自定义异常类
class MyAppError(Exception):
    """应用程序所有自定义异常的基类。"""
    pass

# 2. 创建更具体的异常类
class APIResponseError(MyAppError):
    """当API返回一个意外的或错误的响应时引发。"""
    def __init__(self, message, status_code):
        super().__init__(message)
        self.status_code = status_code

# 3. 在代码中使用它
def get_user_data(user_id):
    # response = requests.get(f"https://api.example.com/users/{user_id}")
    # 模拟一个失败的响应
    status_code = 500
    if status_code != 200:
        raise APIResponseError(f"Failed to fetch data, API returned {status_code}", status_code)
    # return response.json()

# 4. 捕获它
try:
    get_user_data(123)
except APIResponseError as e:
    print(f"Error communicating with API: {e}")
    print(f"Status code was: {e.status_code}")
except MyAppError as e:
    print(f"An application-specific error occurred: {e}")

总结

使用 内置异常 来表示通用的编程错误(如 ValueError, TypeError)。

使用 NotImplementedError 来定义接口和抽象方法,强制子类实现。

使用 AssertionError 进行内部调试和状态检查。

当内置异常不足以描述你的特定问题域时,创建自定义异常,以提高代码的清晰度和健壮性。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文