关于oop:python中的链调用父构造函数

Chain-calling parent constructors in python

本问题已经有最佳答案,请猛点这里访问。

考虑一下这一点-从A继承的基类A、从B继承的类B、从B继承的类C。在构造函数中调用父类构造函数的一般方法是什么?如果这听起来仍然太模糊,这里有一些代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A(object):
    def __init__(self):
        print"Constructor A was called"

class B(A):
    def __init__(self):
        super(B,self).__init__()
        print"Constructor B was called"

class C(B):
    def __init__(self):
        super(C,self).__init__()
        print"Constructor C was called"

c = C()

我现在就是这样做的。但它看起来仍然有点非泛型——您仍然必须手工传递正确的类型。

现在,我已经尝试使用self.__class__作为super()的第一个参数,但是,显然它不起作用-如果您将它放入构造函数c中足够公平,B的构造函数就会被调用。如果在B中做同样的操作,"self"仍然指向C的一个实例,因此您最终再次调用B的构造函数(这以无限递归结束)。

现在不需要考虑钻石继承,我只是想解决这个具体的问题。


python 3包括一个改进的super(),它允许如下使用:

1
super().__init__(args)


您这样做确实是推荐的方法(对于python 2.x)。

类是否显式传递给super是一个样式问题,而不是功能问题。将类传递给super符合Python的"显式优于隐式"哲学。


你可以简单地写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A(object):

    def __init__(self):
        print"Constructor A was called"

class B(A):

    def __init__(self):
        A.__init__(self)
        # A.__init__(self,<parameters>) if you want to call with parameters
        print"Constructor B was called"

class C(B):

    def __init__(self):
        # A.__init__(self) # if you want to call most super class...
        B.__init__(self)
        print"Constructor C was called"