【问题标题】:Why dual __init__ in python?为什么在 python 中使用双重 __init__?
【发布时间】:2015-02-16 15:12:05
【问题描述】:

我正在研究 python oop 样式。我似乎__init__的构造方法如下。我以前没见过这种风格。为什么要像这些东西一样使用双重__init__ 方法?

前-

class MinimumBalanceAccount(BankAccount):
    def __init__(self, minimum_balance):
        BankAccount.__init__(self)
        self.minimum_balance = minimum_balance

    def withdraw(self, amount):
        if self.balance - amount < self.minimum_balance:
            print 'Sorry, minimum balance must be maintained.'
        else:
            BankAccount.withdraw(self, amount)

【问题讨论】:

标签: python oop inheritance super


【解决方案1】:

这是 Python 中的类继承示例。您已将 BankAccount 类继承到 MinimumBalanceAccount 类。但是,通过在MinimumBalanceAccount 类中引入__init__ 函数,您已经覆盖了BankAccount 类的__init__ 函数。基类可能会初始化您需要的一些变量。因此它在 Child 类的 __init__ 构造函数中被调用以确保这一点。

您可以使用super 类来实现相同的行为。 在 Python 2.x 中,等价的将是

class MinimumBalanceAccount(BankAccount):
    def __init__(self, minimum_balance):
        self.minimum_balance = minimum_balance
        super(MinimumBalanceAccount, self).__init__()

或者在 Python 3.x 中,

class MinimumBalanceAccount(BankAccount):
    def __init__(self, minimum_balance):
        super().__init__()

但是,您必须了解,这只会运行它首先从基本方法中找到的任何 __init__ 方法。所以在多重继承方面,如果基类中没有实现super,就很难调用其他各种类的__init__方法。所以请不惜一切代价避免使用多重继承或在所有类中实现super

(eg)

class BankAccount(object):
    def __init__(self):
        # Some action here
        # But no super method called here

class MinimumBalanceAccount(BankAccount, LoanAccount):
    def __init__(self, minimum_value):
        super(MinimumBalanceAccount, self).__init__() # Calls BankAccount.__init__()
        super(MinimumBalanceAccount, self).__init__() # Still calls the same

如果您仍然希望使用多重继承,最好使用ParentClass.__init__ 方法或在所有基类中将super 方法调用添加到__init__

【讨论】:

  • “但是,你必须明白,这只会运行它首先从基本方法中找到的任何 init 方法。” => 抱歉,但这至少部分是错误的。 - 只要父类__init__ 方法自己调用super().__init__(),那么所有父类的初始化程序都会以正确的顺序调用(即__mro__ 顺序)。
  • 是的。如果父类中有super调用。然后通过一个 super 语句,我们将遵循整个决议。但是,如果基类中没有超级方法,我们只能通过类名调用第二个__init__ 方法。我会更详细地更新帖子。
【解决方案2】:

MinimumBalanceAccount 类派生自BankAccount 类。因此,在类的init函数中,需要调用基类的init,由BankAccount.__init__(self)完成。

【讨论】:

    【解决方案3】:

    这无非是变相调用ParentClass.__init__(),即

    super(ChildClass, self).__init__()
    

    首选的 Python 风格是显式使用 super,而不是在父类的名称中硬编码。

    (在 Python 3.x 中:你可以直接说 super().__init__()

    所以这实际上只是Understanding Python super() with init() methods 的伪装;这里,ChildClassMinimumBalanceAccount

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-26
      • 1970-01-01
      • 1970-01-01
      • 2011-11-06
      • 2020-11-06
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      相关资源
      最近更新 更多