【问题标题】:Why not assign __init__ to superclass's __init__?为什么不将 __init__ 分配给超类的 __init__?
【发布时间】:2012-05-23 22:10:45
【问题描述】:

为什么我在 Python 代码中看不到以下内容?

class A:
    def __init__(self, ...):
        # something important

class B(A):
    __init__ = A.__init__

它似乎在我的机器上运行 Python 2.5、2.6、2.7 和 PyPy 1.8。

我经常看到以下内容:

class B(A):
    def __init__(self, *args, **kwargs):
        A.__init__(self, *args, **kwargs)

或者使用super的东西。

我更喜欢我的第一个示例(显式优于隐式!)但我担心由于某种原因它不符合犹太教规。它有什么问题或坏处吗?

编辑:是的,我的意思是A.__init__,而不是self.__init__

【问题讨论】:

  • 我不明白__init__ = self.__init__ 在这种情况下会如何做任何事情。 self 不是 Python 中的关键字。
  • 我想,也许是__init__ = A.__init__
  • 有什么理由打扰吗?如果您没有在子类中声明一个,父类的构造函数将被继承。只有在做额外的事情时才需要覆盖它。
  • 如果您看到该结构(即,__init__ 中没有额外的代码)我会怀疑代码是由没有 Python 经验的人编写的,并且习惯于用另一种语言做这些事情
  • @gnibbler 或者它可能是一个存根。我想不出一种语言,你必须重写子类中除了调用 super 什么都不做的方法。

标签: python


【解决方案1】:

当然,它会起作用(假设您做对了,但在您的示例中没有这样做),但没有理由这样做。如果您希望B 调用A__init__(),请不要在B 上定义__init__(),这将自动发生。毕竟,这就是继承的全部意义。

您想要为B 编写__init__() 的唯一原因是,如果您想在初始化B 实例时做一些事情除了什么是初始化A 实例。在这种情况下,除了调用 A.__init__() 之外,您还需要编写额外的代码,因此简单的赋值也不适合。

如果你想保护B__init__() 不被猴子补丁更改为A,我想你可以使用它。但这似乎是一个边缘案例。更糟糕的是,这是出人意料的行为,是对 Python 动态特性的公然否认。

【讨论】:

  • "protect ... monkey-patch" 除了它不会那样做,因为查找是在运行时完成的,而不是编译时。
  • 但是类定义也会在运行时发生。这只是首先发生的事情:在这种情况下,唯一影响 B 类的 A 类补丁是在 B 类加载之前应用的补丁,如果它们在同一个模块中,则可能没有。
  • 你是对的,它默认调用超类的__init__ 方法。我从来没有意识到这一点,因为我总是看到像我的第二个例子这样的代码——那么为什么人们会这样写呢? (例如,stackoverflow.com/questions/6535832/…
  • @ChrisMorgan 我经常看到这样的现实代码。我猜这只是被复制的糟糕代码。
  • @MichaelMaltese:我也偶尔看到过类似的真实代码。这很糟糕。
猜你喜欢
  • 2011-04-16
  • 2016-11-06
  • 1970-01-01
  • 1970-01-01
  • 2013-06-20
  • 2021-05-27
  • 2020-10-10
  • 2011-09-26
  • 2021-06-10
相关资源
最近更新 更多