抽象基类:在__init __。py`中引发NotImplementedError()?

时间:2015-09-03 09:40:21

标签: python pycharm

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()

但是,如果我将其调用,则课程AbstractBase会引发NotImplementedError

我是一只羊,不知道如何继续: - )

4 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:4)

您可以考虑using the abc Abstract Base Class module__init__标记为抽象,然后继续从子类调用超类__init__(并且,如DorElias suggested,给出超类__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:无法使用抽象方法 init

实例化抽象类AbstractBase

所以你已经获得了不可替代的抽象安全性,但与此同时,你仍然可以通过改变基类构造来改变所有的子类构造,这是正确的。

答案 2 :(得分:0)

在抽象类中用

替换 init 函数中的异常
Thread

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

答案 3 :(得分:0)

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

这允许您调用超级__init__,但这并不一定意味着您应该这样做,因为它仍然无能为力。这是个人喜好,Pycharm对此发出警告是错误的。

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