初始化多个超类 Python

1 投票
1 回答
750 浏览
提问于 2025-04-16 19:15

我该如何在Python中初始化多个父类呢?

举个例子:

class A (B, C):
    def __init__(self, param):
        B.__init__(self)
        C.__init__(self, param)
    #
#

1 个回答

6

你的原始代码是可以工作的,写得很清晰易读。调用的方式也很明确,你可以用 A(p) 或者 A(param=p) 来创建 A 的实例。

class A(B, C):
    def __init__(self, param):
        B.__init__(self)
        C.__init__(self, param)

你也可以使用 super,它的好处在于可以把对 B.__init__C.__init__ 的两个明确调用,替换成一个对 super(A,self).__init__ 的调用,这样看起来更简洁:

class B(object):
    def __init__(self, **kwargs):
        print('B')
        super(B,self).__init__(**kwargs)

class C(object):
    def __init__(self, **kwargs):
        print('C')
        self.param=kwargs.pop('param',None)
        super(C,self).__init__(**kwargs)

class A(B, C):
    def __init__(self, **kwargs):
        print('A')
        super(A,self).__init__(**kwargs)

a=A(param=1)

# A
# B
# C

不过,使用 super 也有一些不小的代价:

  1. 所有类的 __init__ 调用方式必须一致。因为 AC 有一个 param 参数,而 B 没有,所以你需要修改这三个类,让它们都使用更模糊(但统一!)的 **kwargs 参数。这样一来,调用的方式就不再明确了。

  2. 现在,A 只能用 A(param=p) 来创建实例,而不能再用 A(p) 了。

  3. 更糟糕的是(正如 Sven Marnach 在评论中提到的),传给 A 的每个参数都必须在某个时刻从 kwargs 中取出来,因为 object 不接受任何参数。一旦某个类(比如 C)从 kwargs 中取出一个参数,其他类(比如 B)就不能再使用同样的参数名了。因此,参数的命名需要在所有类之间进行协调,尽管理想情况下,BC 应该是相互独立的。

  4. 代码变得更加冗长和复杂,阅读起来不那么容易。

所以,我一般不太喜欢使用 super(就像你的原始代码一样),除非使用 super 带来的间接好处大于上述提到的成本。

撰写回答