抽象基础 class:在 `__init__.py` 中引发 NotImplementedError()?

Abstract base class: raise NotImplementedError() in `__init__.py`?

PyCharm 警告我 Call to __init__ of super class is missed

class AbstractBase(object):
    def __init__(self):
        raise NotImplementedError()

class RealChild(AbstractBase):
    def __init__(self):
        #super(RealChild, self).__init__() ####
        print('do stuff')

child=RealChild()

但是如果我调用它,class AbstractBase 将加注 NotImplementedError

我是一只羊,不知道如何进行:-)

在摘要class中用

替换init函数中的异常
pass

此异常用于防止您初始化抽象的新实例class(它是抽象的,所以您不能) 所以要么使用 'pass' 要么不听 pycharm 并且不要调用 super

你可以做一些丑陋的事情,并在抽象类型的初始化器中检查 self 的类型,以确保它是子类型的:

class AbstractBase (object):
    def __init__ (self):
        if type(self) is AbstractBase:
            raise NotImplementedError

我认为更“正常”的方法是不公开抽象基类型并期望用户不要创建它。

您可以考虑 using the abc Abstract Base Class module to mark __init__ as abstract, and then go ahead and invoke the superclass __init__ from the subclass (and, as ,给超级 class __init__ 一个 pass 的简单实现):

from abc import ABCMeta, abstractmethod


class AbstractBase(object, metaclass=ABCMeta):
    @abstractmethod  # This method must be overridden...
    def __init__(self):
        print("...but can still be called via super by subclasses have shared construction logic")
        pass


class RealChild(AbstractBase):
    def __init__(self):
        super().__init__()  # Won't do anything, UNTIL the day you decide all subclasses of AbstractBase need shared logic
        print('do stuff')


child = RealChild()

如果您尝试通过 parent = AbstractBase()parent = AbstractBase.__new__(AbstractBase) 实例化,您将得到一个错误:

TypeError: Can't instantiate abstract class AbstractBase with abstract methods init

所以你得到了你不可实例化的抽象安全,但与此同时你仍然准备好通过改变基础 class 构造来改变所有子 class 构造,这是正确的并且正确的。

@Bryant 的 正确解释了您应该使用 @abstractmethod 而不是手动引发 NotImplementedError

这允许您调用超级 __init__,但这并不一定意味着您应该这样做,因为它仍然不执行任何操作。这是个人品味问题,Pycharm 发出警告是错误的。

所以我的替代答案是:忽略 Pycharm 并希望他们有一天能解决这个问题。