Как немного изменить унаследованный атрибут от родительского __init __ () с минимальными изменениями в дочернем классе в Python? - PullRequest
1 голос
/ 07 мая 2020

Код, как показано ниже:

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_function4 к self.datacollector в ChildClass, без необходимости полностью перезаписывать родительский __init__() и повторять весь код параметра. Мы будем благодарны за любые советы или предложения.

--- Редактирование ---

Чтобы объяснить более подробно. Основываясь на предложениях, я бы создал дочерний класс как ChildClass1. Однако у моего класса много параметров при инициализации. Мне не только нужно записать их все в дочернем классе __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

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Вызов 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)

[edit] -----------

Вы можете использовать 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)
0 голосов
/ 07 мая 2020

Если я правильно понял ваш вопрос, будет ли следующее делать то, что вы ищете?

class MaybeWorks:
    def __init__(self, num_funcs, *args):
        for k, arg in enumerate(args):
            setattr(self, 'param'+str(k+1), arg)
        data_reporter=dict()
        for k in range(num_funcs):
            data_reporter['Report info '+str(k+1)] = globals()['some_function'+str(k+1)]
        self.datacollector = ReporterClass(data_reporter)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...