【问题标题】:Error "__init__ method from base class is not called" for an abstract class抽象类的错误“未调用基类的 __init__ 方法”
【发布时间】:2014-08-01 03:18:20
【问题描述】:

我有

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,所以这也不是一个选项)。

【问题讨论】:

  • 我不知道你在哪里使用了抽象类。如果你想在 B 中继承类 A,并且想在 B 中定义 init,那么请使用 super 代替。它是 abc 类的错误实现
  • 我可以发誓当我读到它时它不存在。您是否记得使用模块名称和/或from abc import abstractmethod 来限定abstractmethod

标签: python pylint


【解决方案1】:

忽略 pylint。它只是一个不考虑抽象类的程序。相信你比它更聪明。 Pylint 是护膝,不是拐杖。

【讨论】:

  • 感谢您的称赞,但我不想在生产代码中看到任何警告或错误。
  • 在这种情况下,您倾向于货物崇拜编程。 “没有警告”的标准太高,不能避免浪费精力。不过,this answer 应该会给你一些帮助。
  • @sds 您仍然可以针对这种特定情况在本地禁用消息
  • 你没有给 pylint 足够的信任,我认为:它很好地理解抽象类(例如,如果你忘记实现抽象方法,它会警告你)
【解决方案2】:

使用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 更了解。

【讨论】:

  • aha,所以解决方案是使用@abc.abstractmethod 而不是@abstractmethod。谢谢。
  • @sds 不是。解决方案是在 A.__init__() 中使用 pass 而不是 raise NotImplementedError("A")
  • 从 pylint 的角度来看最好的解决方案,但是调用抽象方法很奇怪......设计的抽象方法存在被覆盖,而不是调用
  • 这不会阻止 A 被实例化。
【解决方案3】:

empty __init__ 定义为抽象方法并不是很有用。

相反,让A 继承自ABCABstract Class),并在真正需要由用户。

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,你不会遇到问题。

【讨论】:

  • Defining __init__ as an abstract method is not very useful. = 不正确,当您定义接口类及其方法头并且您希望在对象创建时定义/完成某些设置。当然你可以先a = MyClass() 然后a.my_init() 但是为什么...
  • @jave.web 你是对的,我已将其更正为 empty __init__
猜你喜欢
  • 2017-12-13
  • 1970-01-01
  • 1970-01-01
  • 2012-12-15
  • 2020-03-12
  • 1970-01-01
  • 1970-01-01
  • 2013-05-10
  • 2015-04-11
相关资源
最近更新 更多