Как автоматизировать прохождение повторяющихся kwargs на экземпляре класса

1

Я пытаюсь использовать композицию над концепцией дизайна наследования, и я сохраняю создателя и main_actor для каждого компонента. Это выглядит очень повторяющимся и уродливым, поэтому мне интересно, есть ли способ сделать его приятнее.

class ComponentA:
    def __init__(self, **kwargs):
        self.creator    = kwargs['creator']
        self.main_actor = kwargs['main_actor']
        self.b          = ComponentB(creator=self, main_actor=self.main_actor)
        self.c          = ComponentC(creator=self, main_actor=self.main_actor)

        # instead of that, i want to achieve the same, 
        # without the eye sore of the repetitive kwargs:

        self.b = ComponentB()
        self.c = ComponentC()

        # perhaps with metaclasses? or a function? 

        self.b = make(ComponentB)
        self.c = make(ComponentC)
Теги:

2 ответа

0
Лучший ответ

Их состав и наследование имеют свое место. Чтобы избежать повторения в ваших классах компонентов, я бы использовал наследование таким образом:

class Component(object):

    def __init__(self, **kwargs):
        for name in ('creator', 'main_actor'):
            setattr(self, name, kwargs[name])

        component_class = type(self)
        for attr in dir(component_class):
            if not attr.startswith('__'):
                sub_component_class = getattr(component_class, attr)
                if issubclass(sub_component_class, Component):
                    setattr(self, attr, sub_component_class(**{**kwargs, 'creator': self}))


class ComponentB(Component):
    pass


class ComponentC(Component):
    pass


class ComponentA(Component):
    b = ComponentB
    c = ComponentC

# In [0]: a = ComponentA(creator='me', main_actor='fred')
# 
# In [1]: a.creator
# Out[1]: 'me'
# 
# In [2]: a.b
# Out[2]: <__main__.ComponentB at 0x7f6def403550>
# 
# In [3]: a.b.creator
# Out[3]: <__main__.ComponentA at 0x7f6def47cc18>
# 
# In [4]: a.b.main_actor
# Out[4]: 'fred'
# 
# In [5]: a.c.main_actor
# Out[5]: 'fred'
0

Я не уверен, как это pythonic, но вы можете попробовать следующее:

class ComponentA:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

        self.b = self.make(ComponentB)
        self.c = self.make(ComponentC)

    def make(self, component):
        return component(creator=self, main_actor=self.main_actor)

class ComponentB:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

class ComponentC:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

a = ComponentA(creator=None, main_actor='MAIN_ACTOR')

print(a.b.main_actor)


>>> 'MAIN_ACTOR'

Редактировать: Смотрите ли я.__ dict __. обновление (** kwargs) хорошего или плохого стиля? для получения дополнительной информации об этом решении.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню