关于python:如何在类实例化时自动传递重复的kwargs

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)好或坏的风格? 有关此解决方案的更多信息。