抽象基础 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 并希望他们有一天能解决这个问题。
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 __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 并希望他们有一天能解决这个问题。