CodeGym /课程 /Python SELF ZH /创建自定义异常

创建自定义异常

Python SELF ZH
第 18 级 , 课程 1
可用

7.1 创建自定义异常

有时候,Python 的标准异常不能完全满足你应用程序的需求。这种情况下,你可以通过继承基本类 Exception 或其他适合的异常类来创建自己的异常。

创建自定义异常的基础

创建自定义异常包括定义一个新类,该类继承自基本类 Exception。你可以在你的异常类中添加自己的方法和属性,以提供有关错误的额外信息。

创建简单自定义异常的示例

步骤 1: 定义自定义异常


class MyCustomError(Exception):
    """自定义异常类。"""
    pass
        

步骤 2: 使用自定义异常


def check_value(value):
    if value < 0:
        raise MyCustomError("值不能小于零")
            
try:
    check_value(-1)
except MyCustomError as e:
    print(f"发生了自定义异常: {e}")
            

非常简单。关键是你的异常要从 Exception 类或其继承类之一继承。

7.2 创建带有附加属性的异常

你可以在你的异常类中添加属性和方法,以传递有关发生错误的附加信息。

示例:


class NegativeValueError( Exception ):
    """在值为负时的自定义异常类。"""
    def __init__(self, value, message = "值不能小于零"):
        self.value = value
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f'{self.message}: {self.value}'

使用带有附加属性的异常


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)

try:
    check_value(-1)
except NegativeValueError as e:
    print(f"发生了自定义异常: {e}")

我们的异常是继承自 Exception 的类。因此,它可以像其他类一样添加字段、方法、构造函数参数等。

为了你的方便以及那些将要捕获你的异常的程序员的方便。

7.3 创建自定义异常的层次结构

对于更复杂的应用程序,创建自定义异常的层次结构是有用的。这可以将相关异常分组,使其处理更简单。

示例:


class ApplicationError(Exception):
    """应用程序所有异常的基类。"""
    pass

class NegativeValueError(ApplicationError):
    """在值为负时的自定义异常类。"""
    def __init__(self, value, message="值不能小于零"):
        self.value = value
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f'{self.message}: {self.value}'

class ValueTooLargeError(ApplicationError):
    """当值过大时的自定义异常类。"""
    def __init__(self, value, message="值太大"):
        self.value = value
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f'{self.message}: {self.value}'

使用自定义异常的层次结构


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)

try:
    check_value(150)
except NegativeValueError as e:
    print(f"发生了异常: {e}")
except ValueTooLargeError as e:
    print(f"发生了异常: {e}")
except ApplicationError as e:
    print(f"应用程序的常规异常: {e}")

7.4 捕获异常的顺序

在捕获异常时,特别是从同一层次结构中,指明它们的正确顺序非常重要。虽然 except 块中的代码从不同时执行,但原因在于基本异常类可以捕获所有子类异常

例如,代码:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
    
try:
    check_value(150)
except ApplicationError as e: # 捕获 ApplicationError 类型及其所有子类异常
    print(f"应用程序的常规异常: {e}")

except 块中会捕获 ApplicationError 类型及其类的派生类异常。

由于所有异常都是 Exception 类的子类,因此这样的代码会捕获所有异常:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
    
try:
    check_value(150)
except Exception as e:
    print(f"捕获所有异常: {e}")
except ApplicationError as e: # 这段代码永远不会执行
    print(f"应用程序的常规异常: {e}")

except ApplicationError 块中的异常捕获将永远不会发生,因为 except Exception 块会捕获所有类型为 Exception 的异常和任何子类。

解决方案

因此,捕获异常通常按照与继承相反的顺序:类越接近 Exception 类,就越低。

示例:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
        
try:
    check_value(150)
except NegativeValueError as e:
    print(f"发生了异常: {e}")
except ApplicationError as e:
    print(f"应用程序的常规异常: {e}")
except Exception as e:
    print(f"捕获所有异常: {e}")

在这个示例中,except 块的顺序与它们的继承层次结构一致:首先捕获更具体的异常,如 NegativeValueError,然后是更一般的,如 ApplicationError。 这样可以正确处理异常,避免出现更一般的处理程序在更具体的 except 块之前捕获异常的情况。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION