我试图在继承设计概念上使用组合,并且一直在存储每个组件的创建者和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)
答案 0 :(得分: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'
编辑:有关此解决方案的更多信息,请参见Is self.__dict__.update(**kwargs) good or poor style?。
答案 1 :(得分: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'