首页 > 解决方案 > 如何在 Python 中对子类的更改最小的情况下稍微修改从父 __init__() 继承的属性?

问题描述

代码如下:

def some_function1():
    pass

def some_function2():
    pass

def some_function3():
    pass

def some_function4():
    pass

class ReporterClass():
    def __init__(self, data_reporter):
        self.data_reporter = data_reporter

class ParentClass():
    def __init__(self, param1, param2):
        self.param1 = param1
        self.param2 = param2
        self.datacollector = ReporterClass(data_reporter={
            'Report info 1': some_function1,
            'Report info 2': some_function2,
            'Report info 3': some_function3,
            })

class ChildClass(ParentClass):
    def __init__(self, param1, param2):
        self.param1 = param1
        self.param2 = param2
        self.datacollector = ReporterClass(data_reporter={
            'Report info 1': some_function1,
            'Report info 2': some_function2,
            'Report info 3': some_function3,
            'Report info 4': some_function4,
            })

这在这个玩具示例中效果很好,但我在实际代码中遇到的问题是 中有很多参数__init__(),例如param1... param100。类似地, 中有许多字典项data_reporter,例如Report info 1... Report info 100。我喜欢简单地通过添加'Report info 4': some_function4self.datacollectorin 中进行修改,ChildClass而不必完全覆盖父级__init__()并且不必重复所有参数代码。任何提示或建议将不胜感激。

--- 编辑 ---

更详细地解释。根据建议,我会将子类创建为ChildClass1. 但是,我的类在初始化中有很多参数。我不仅需要将它们全部写在 child class'__init__()中,我还需要在super().__init__(). 所以我想知道是否有更方便和优雅的方式不必重复自己。类似的东西ChildClass2

class ChildClass1(ParentClass):
    def __init__(self, 
                        param1, 
                        param2,
                        ., # Very long list of parameters
                        .,
                        .,
                        param100,
    ):
        super().__init__(
                        param1, 
                        param2,
                        ., # Very long list of parameters
                        .,
                        .,
                        param100
                        )
        self.datacollector.data_reporter['Report info 4'] = some_function4

class ChildClass2(ParentClass):
    def __init__(self, *args):
        some_var_to_store_parent_init_params = super().__init__.attr

        for param in some_var_to_store_parent_init_params:
            # somehow assign it back to ChildClass' args

        super().__init__(some_var_to_store_parent_init_params)

        self.datacollector.data_reporter['Report info 4'] = some_function4

标签: python-3.xclassoopinheritanceinitialization

解决方案


调用super()__init__()将帮助您很好地重用父级__init__;然后您可以在 'ReporterClass.datacollector' 属性中添加必要的附加功能ChildClass

您可以进一步重构ReporterClass.datacollector构建方式以使用参数填充它 - 相反,在这里,在调用super().

def some_function1(): pass    
def some_function2(): pass
def some_function3(): pass
def some_function4(): pass


class ReporterClass:
    def __init__(self, data_reporter):
        self.data_reporter = data_reporter


class ParentClass:
    def __init__(self, param1, param2):
        self.param1 = param1
        self.param2 = param2
        self._data_reporter = {'Report info 1': some_function1,
                               'Report info 2': some_function2,
                               'Report info 3': some_function3}
        self.datacollector = ReporterClass(self._data_reporter)


class ChildClass(ParentClass):
    def __init__(self, param1, param2):
        super().__init__(param1, param2)
        self.datacollector.data_reporter['Report info 4'] = some_function4


if __name__ == '__main__':

    print(ParentClass(1, 2).datacollector.data_reporter)
    print(ChildClass(3, 4).datacollector.data_reporter)

[编辑] - - - - - -

如果您发现处理许多参数很麻烦,您可以使用 args、kwargs,如下所示:

class ParentClass:
    def __init__(self, *args):
        self.param1, self.param2 = args
        self._data_reporter = {'Report info 1': some_function1,
                               'Report info 2': some_function2,
                               'Report info 3': some_function3}
        self.datacollector = ReporterClass(self._data_reporter)


class ChildClass(ParentClass):
    def __init__(self, *args):
        super().__init__(*args)
        self.datacollector.data_reporter['Report info 4'] = some_function4


if __name__ == '__main__':

    print(ParentClass(1, 2).datacollector.data_reporter)
    print(ChildClass(3, 4).datacollector.data_reporter)

推荐阅读