当我们有NotImplementedError时,为什么还需要抽象基类库呢?

Pau*_*gel 8 python inheritance

以下是 python 中抽象基类的典型用法:

from abc import ABC

class MyBaseClass(ABC):
    @abstractmethod
    def __init__(self):
        print("Here's some logic that I want all subclasses to have")

class ChildClass(MyBaseClass):
    def __init__(self):
        super().__init__()
        print("Here's some additional logic that I want this subclass to have")
Run Code Online (Sandbox Code Playgroud)

行为是:不可能实例化MyBaseClass,但可以对其进行子类化,并MyBaseClass包括所有子类继承的逻辑。

这是获得相同行为的另一种方法:

class MyBaseClass:
    def __init__(self):
        if type(self) == MyBaseClass:
            raise NotImplementedError
        print("Here's some logic that I want all subclasses to have")

class ChildClass(MyBaseClass):
    def __init__(self):
        super().__init__()
        print("Here's some additional logic that I want this subclass to have")
Run Code Online (Sandbox Code Playgroud)

据我所知,这种方法具有完全相同的行为,具有相同数量的代码,同样明确,并且仅使用本机 Python。那么ABC这种方法无法处理什么问题呢?

Kra*_*las 9

抽象基类会阻止您实例化对象,除非您实现抽象方法。这会立即引发错误并提醒您需要实现该方法。NotImplementedError如果您实例化该类,但直到经过漫长的执行过程才调用该方法,这尤其有用:在调用该方法之前,您不会引发异常。

import abc

class AbstractClass(abc.ABC):
    @abc.abstractmethod
    def test(self):
        pass

class NotAbstractClass:
    def test(self):
        raise NotImplementedError()

class AbstractInheritor(AbstractClass):
    pass

class NotAbstractInheritor(NotAbstractClass):
    pass

x = AbstractInheritor() # raises error immediately
y = NotAbstractInheritor() # no error despite not implementing test
Run Code Online (Sandbox Code Playgroud)

事实上,我创建的行x被我的类型检查器捕获,所以我什至不需要运行代码就知道存在问题。同时,y一切都很好。