【问题标题】:Why calling base class contructor is mandatory?为什么调用基类构造函数是强制性的?
【发布时间】:2020-03-17 18:47:49
【问题描述】:

我想知道为什么在 Python 中,派生类必须调用其基类的构造函数才能继承所有实例属性。

例如:

class A:
   def __init__(self):
   self.a = 0

class B(A):
   def __init__(self):
   super().__init__()   # this is mandatory in order to inherit A's instance attributes 
   self.b = 1

a = A()
b = B()
print(b.a)                # this gives an error it the line super().__init__() is omitted 

但是,在其他编程语言中,调用基类构造函数是不必要的。

【问题讨论】:

  • 因为与其他语言不同,python类变量都是在构造函数中定义和初始化的
  • 子类覆盖 __init__() 而不是从父类继承它,因此它需要一种方式来表示“去做我父母的__init__() 会做的所有事情。”

标签: python inheritance


【解决方案1】:

首先,调用超类的__init__ 方法不是强制。如果您需要它在子类中的行为,您只需要这样做。如果您的子类正在做不同的事情,您可以跳过调用。

例如,如果基类进行了昂贵的计算,但子类用于特殊情况,可以使用更快的计算,您可以像这样跳过昂贵的调用:

class Base():
    def __init__(self, x):
        self.a = expensive_computation(x)

class NormalDerived(Base):
    def __init__(self, x):
        super().__init__(x) # Base.__init__ does the expensive computation for us
        self.b = something_else(x)

class SpecialCaseDerived(Base):
    def __init__(self, x):
        # don't call super here,  instead, do a different computation for "a" ourselves
        self.a = cheaper_computation(x)
        self.b = something_else(x)

【讨论】:

    【解决方案2】:

    与其他语言不同,python中的实例变量都是在构造方法中定义和初始化的。

    更一般地,实例变量只能在方法中定义,而不是在类定义中。这是python在设计和实现方式上的一个特性。

    例如:Understanding class and instance variables in Python 3

    因此,对于您的示例,如果您想继承实例变量,则必须调用超级构造函数,否则再次重新定义它们。

    【讨论】:

      猜你喜欢
      • 2017-12-21
      • 2013-01-28
      • 2010-09-12
      • 2012-02-28
      • 2012-05-19
      • 1970-01-01
      • 2011-02-24
      • 1970-01-01
      相关资源
      最近更新 更多