How to automate passing repetitive kwargs on class instantiation
我试图使用一个组合而不是继承设计概念,我一直在存储每个组件的creator和main_actor。 这整体看起来非常重复和丑陋,所以我想知道是否有办法让它变得更好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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) |
组成和继承都有自己的位置。 为了避免在组件类中重复,我会使用继承:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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' |
我不确定pythonic是多少,但您可以尝试以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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)好或坏的风格? 有关此解决方案的更多信息。