python - PyLint W0231 super-init-not-called with __init__ of 祖 parent

标签 python inheritance pylint method-resolution-order

我创建了一个 Child 类,它使用 Parent 类中不存在于 GrandParent 中的方法。但在 Child.__init__() 类中,我不想从 Parent.__init__() 获得一些效果,而是调用 call GrandParent.__init__( )

class GrandParent():
    ...

class Parent(GrandParent):    
    def __init__(self):
        GrandParent.__init__(self)
        ...


class Child(Parent):
    def __init__(self):
        GrandParent.__init__(self)
        ...

使用此代码,我收到来自 pylint 的下一个警告

 W0233: __init__ method from a non direct base class 'GrandParent' is called (non-parent-init-called)
 W0231: __init__ method from base class 'Parent' is not called (super-init-not-called)

修复此警告的正确方法是什么?

(或者为 Child 禁用此警告是正确的解决方案吗?)

class Child(Parent):
    def __init__(self):  # pylint: disable=W0233
        GrandParent.__init__()   # pylint: disable=W0231
        ...  

最佳答案

您可以尝试多种方法,例如:

GrandParent.__init__(self)
super().super().__init__(self)
super(GrandParent, self).__init__()

但错误仍然存​​在,如下所示:

  • 未调用 super 初始化
  • bad-super-call (super(GrandParent, self)...)
  • 或者甚至作为对直接父级的无用 super 调用。

我想这意味着如果您使用继承,并且可以使用 pylint 禁用来关闭它,则不会错误地初始化类 __mro__ 中的直接类:

# pylint: disable=super-init-not-called

但是这样的调用会扰乱 __mro__ 链。

您可以做的是允许通过 Child.__mro__ 项目向上级联,即 Child -> Parent -> GrandParent (-> object),同时在 __init__ 中按类引用跳过:

class Parent(GrandParent):
    def __init__(self):
        super().__init__()
        if self.__class__ == Child:
            return

它不会触发 PyLint 警告,并明确允许正确的行为,并且不会跳过 __mro__ 中的任何必需项目。

IMO 它更清晰地保留了 __mro__ 这似乎也是 PyLint 的意图以及 super-init-not-used 警告。另一方面,这有点棘手,并且将代码隐藏在完全不同的类中,如果缺少 Parent 的某些属性并且没有注释/禁用警告,这将使将来的调试变得烦人。存在于 Child 类中。

如果您只想从 GrandParent 类中提取方法,只需使用“mixins”类,这就是 Django REST Framework is using并且不要为这些编写任何 __init__ (或者如果,那么不要忘记 super().__init__() 继续在 __mro__链!)。

class GrandParent:
    def __init__(self):
        print("> GrandParent __init__()")

class Mixin:
    def mymethod(self):
        print("Hey")

class Parent(Mixin, GrandParent):
    def __init__(self):
        print("> Parent __init__()")
        super().__init__()

class Child(Mixin, GrandParent):
    def __init__(self):
        print("> Child __init__()")
        super().__init__()

Child().mymethod()
# > Child __init__()
# > GrandParent __init__()
# Hey

Parent().mymethod()
# > Parent __init__()
# > GrandParent __init__()
# Hey

这基本上与 Child -> Parent -> GrandParentMixin 的情况相同本身没有(任何有用的)__init__,这将导致您的代码仅从 GrandParent 执行,因为 Mixin.__init__() 为空因此,在视觉上与 if self.__class__ == Child: return 执行相同的操作,但没有任何 hack + 增加了可读性。

关于python - PyLint W0231 super-init-not-called with __init__ of 祖 parent ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62119090/

相关文章:

c++ - 我可以强制继承一个类吗?

git - Pylint 和预提交 python 3.7

python - Pylint白名单模式

python - 为什么我的圆锥/角度渐变图像失真?

python - 取消选中 PyQt5/PySide2 中所有其他复选框的一个复选框

python - ./(点斜杠)运算符在 Python 中代表什么?

python - 如何禁用特定文件的 pylint 错误消息?

python - 计算器的 Python 代码中的回溯错误

java - 需要帮助编译此迭代和接口(interface)程序

c++ - 当我按值传递参数时对象被破坏了?