Python: 继承父类的 __init__

85 投票
7 回答
91361 浏览
提问于 2025-04-16 20:35

我有一个基类,这个类的初始化方法有很多参数:

class BaseClass(object):
    def __init__(self, a, b, c, d, e, f, ...):
        self._a=a+b
        self._b=b if b else a
        ...

所有继承这个基类的子类都应该运行基类的初始化方法。

我可以在每个继承类里写一个初始化方法,去调用父类的初始化方法,但这样会导致代码重复,麻烦得很:

class A(BaseClass):
    def __init__(self, a, b, c, d, e, f, ...):
        super(A, self).__init__(a, b, c, d, e, f, ...)

class B(BaseClass):
    def __init__(self, a, b, c, d, e, f, ...):
        super(A, self).__init__(a, b, c, d, e, f, ...)

class C(BaseClass):
    def __init__(self, a, b, c, d, e, f, ...):
        super(A, self).__init__(a, b, c, d, e, f, ...)

...

有没有什么更简洁的方式,能自动调用父类的初始化方法呢?

7 个回答

21

如果子类没有做任何额外的事情,完全可以不写子类的 __init__() 方法,这样就会自动调用父类的 __init__() 方法。

但是,如果你的子类在 __init__() 方法里添加了一些额外的操作,而你又不想让它们手动调用父类的 __init__() 方法,你可以这样做:

class BaseClass(object):
    def __new__(cls, a, b, c, d, e, f, ...):
        new = object.__new__(cls)
        new._a=a+b
        new._b=b if b else a
        ...
        return new

class A(BaseClass):
    ''' no __init__() at all here '''

class B(BaseClass):
    def __init__(self, a, b, c, d, e, f, ...):
        ''' do stuff with init params specific to B objects '''

因为 __new__() 方法总是会自动被调用,所以子类里不需要再做其他的工作。

45

你需要明确地写出这些内容,但另一方面,如果你有很多参数,最好使用 *args 来处理位置参数,使用 **kwargs 来处理关键字参数。

class SubClass(BaseClass):
    def __init__(self, *args, **kwargs):
        super(SubClass, self).__init__(*args, **kwargs)
        # SubClass initialization code

另一种你可以使用的技巧是,尽量减少 init 函数中的代码,然后在 init 函数的最后调用一个自定义的函数。这样在子类中,你只需要重写这个自定义函数就可以了。

class BaseClass(object):
    def __init__(self, *args, **kwargs):
        # initialization code
        self._a = kwargs.get('a')
        ...
        # custom code for subclass to override
        self.load()

    def load():
        pass

class SubClass(BaseClass)
    def load():
        # SubClass initialization code
        ...
62
super(SubClass, self).__init__(...)

如果你在处理变量的时候遇到麻烦,可以考虑使用 *args 和 **kw 这两个东西,它们可能会帮你解决问题。

撰写回答