为什么必须强制调用基类构造函数?

时间:2019-11-21 18:38:28

标签: python inheritance

我想知道为什么在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 

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

3 个答案:

答案 0 :(得分:3)

首先,调用超类的__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)

答案 1 :(得分:1)

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

更多常规实例变量只能在方法中定义,而不能在类定义中定义。这是python设计和实现方式的功能。

例如参见:Understanding class and instance variables in Python 3

因此,在您的示例中,如果要继承实例变量,则必须调用超级构造函数,否则请重新定义它们。

答案 2 :(得分:0)

除非在构造函数中定义属性并且不调用父类构造函数,否则不会继承Python中的属性,除非您通过调用super()

手动完成所有操作