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,提问作者Алексей Новиков
相关产品推荐
相关产品推荐

