抽象类出现"未调用基类的__init__方法"错误

13 投票
3 回答
12331 浏览
提问于 2025-04-18 15:36

我有

class A(object):
    def __init__ (self): raise NotImplementedError("A")

class B(A):
    def __init__ (self):
        ....

而pylint说

__init__ method from base class 'A' is not called

显然,我不想这样做

super(B, self).__init__()
  • 那我该怎么办呢?

(我试过abc,结果得到了

Undefined variable 'abstractmethod'

来自pylint的提示,所以这也不是一个选项)。

3 个回答

1

把一个空的 __init__ 定义成抽象方法其实没什么用。

更好的做法是让 A 继承自 ABC(也就是抽象类),然后在那些用户必须实现的方法上加上 @abstractmethod 装饰器。

from abc import ABC, abstractmethod

class A(ABC):
    @abstractmethod
    def cool_method(self):
        raise NotImplemented

这样一来,你就不能直接创建 A 的实例,同时也避免了警告。而且,如果你不实现 A 的默认 __init__ 方法,它的行为大概是这样的:

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)

另外,这样做还有个好处,就是遵循了 mro(方法解析顺序),如果你以后想在多重继承的情况下使用 A,就不会遇到问题。

10

别太在意pylint。它只是一个不考虑抽象类的程序。要相信你比它聪明。pylint就像是护膝,而不是拐杖。

4

使用 abc 对我来说是有效的:

import abc

class A(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def __init__(self):
        pass

class B(A):
    def __init__(self):
        super(B, self).__init__()

我收到了一些警告,但这些警告和 abc 或者父类的 __init__ 没有被调用没有关系:

C:  1, 0: Missing module docstring (missing-docstring)
C:  3, 0: Invalid class name "A" (invalid-name)
C:  3, 0: Missing class docstring (missing-docstring)
R:  3, 0: Too few public methods (0/2) (too-few-public-methods)
C:  9, 0: Invalid class name "B" (invalid-name)
C:  9, 0: Missing class docstring (missing-docstring)
R:  9, 0: Too few public methods (0/2) (too-few-public-methods)
R:  3, 0: Abstract class is only referenced 1 times (abstract-class-little-used)

说实话,我和 @holdenweb 的看法一致。有时候,你比 pylint 更了解情况。

撰写回答