如何在Python中实现同时继承BaseException与ABC的抽象类?
如何创建继承BaseException的抽象异常类
问题背景
需要创建一个继承BaseException的抽象类,要求具备abc.ABC的抽象方法检查机制,但两种尝试均失败:
尝试1:多继承abc.ABC和BaseException
import abc class MyBaseAbstractClass(abc.ABC, BaseException): @abc.abstractmethod def foo(self) -> None: raise NotImplementedError @abc.abstractmethod def bar(self, reference) -> None: raise NotImplementedError class MySecondaryAbstrClass(MyBaseAbstractClass): ... obj = MySecondaryAbstrClass()
问题:未触发抽象方法未实现的错误。因为BaseException的元类优先级高于ABCMeta,导致抽象检查机制失效。
尝试2:指定metaclass=abc.ABC
import abc class MyBaseAbstractClass(BaseException, metaclass=abc.ABC): @abc.abstractmethod def foo(self): raise NotImplementedError @abc.abstractmethod def bar(self, reference) -> int: raise NotImplementedError class MySecondaryAbstrClass(MyBaseAbstractClass): ... obj = MySecondaryAbstrClass()
问题:出现元类冲突错误:
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
原因是BaseException的元类为BaseExceptionMeta,abc.ABC的元类为ABCMeta,直接指定ABCMeta作为元类,违反了“子类元类必须是所有基类元类的子类”的规则。
正确实现方案
创建同时继承ABCMeta和BaseException元类的自定义元类,用它定义抽象异常类:
import abc # 自定义元类:同时继承ABCMeta和BaseException的元类 class ABCExceptionMeta(abc.ABCMeta, type(BaseException)): pass class MyBaseAbstractClass(BaseException, metaclass=ABCExceptionMeta): @abc.abstractmethod def foo(self) -> None: raise NotImplementedError @abc.abstractmethod def bar(self, reference) -> int: raise NotImplementedError # 测试1:未实现所有抽象方法,实例化会触发错误 class BadSecondaryClass(MyBaseAbstractClass): pass # 执行以下代码会报错:TypeError: Can't instantiate abstract class BadSecondaryClass with abstract methods bar, foo # obj = BadSecondaryClass() # 测试2:实现所有抽象方法后可正常实例化 class GoodSecondaryClass(MyBaseAbstractClass): def foo(self) -> None: pass def bar(self, reference) -> int: return 0 obj = GoodSecondaryClass()
原理说明
自定义元类ABCExceptionMeta同时继承ABCMeta和BaseException的元类,既满足了元类的继承规则,又保留了ABCMeta的抽象方法检查能力和BaseException的异常类特性。
内容的提问来源于stack exchange,提问作者Amir Masoud Nourollah
相关产品推荐
相关产品推荐

