You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现子类自动继承父类自定义NotFoundError异常

为子类生成专属的NotFoundError异常

问题描述

运行下述代码时,控制台会错误打印“no number found in class A”,但实际是B类对象中未找到目标数字。需求是仅修改Base类,让继承它的子类各自拥有专属的、继承自Base.NotFoundError的NotFoundError异常。

原代码:

class Base:
    class NotFoundError(Exception):
        pass

    def __init__(self, numbers: list[int]):
        self.numbers = numbers

    def pop_by_val(self, number: int):
        try:
            self.numbers.remove(number)
        except ValueError:
            raise self.NotFoundError()


class A(Base):
    pass


class B(Base):
    pass


a = A([1, 2])
b = B([1, 2])

try:
    a.pop_by_val(1)
    b.pop_by_val(3)
except A.NotFoundError:
    print("no number found in class A")
except B.NotFoundError:
    print("no number found in class B")

解决方案

利用Python的__init_subclass__钩子方法,在子类被定义时自动为其创建专属的NotFoundError类,该类继承自Base.NotFoundError。修改后的Base类如下:

class Base:
    class NotFoundError(Exception):
        pass

    # 子类定义时自动执行该方法
    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        # 为当前子类创建专属的NotFoundError,继承自Base.NotFoundError
        cls.NotFoundError = type(f"{cls.__name__}NotFoundError", (Base.NotFoundError,), {})

    def __init__(self, numbers: list[int]):
        self.numbers = numbers

    def pop_by_val(self, number: int):
        try:
            self.numbers.remove(number)
        except ValueError:
            raise self.NotFoundError()

原理说明

  • __init_subclass__是Python 3.6+引入的类钩子,当任何子类继承Base时,这个方法会被自动调用。
  • 在方法内部,我们通过type()动态创建一个新的异常类,类名以子类名开头(比如ANotFoundError、BNotFoundError),继承自Base.NotFoundError,并将其赋值给子类的NotFoundError属性。
  • 这样A和B各自的NotFoundError就是独立的类,但都继承自基类的异常,既满足继承关系,又能被对应的except分支正确捕获。

运行修改后的代码,控制台会正确打印:no number found in class B。

内容的提问来源于stack exchange,提问作者Алексей Новиков

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 01:25:27