如何顺序和有条件地链接不同类的实例化

时间:2017-11-30 23:23:03

标签: python

基本上,我有一个类列表,它们接受相同的输入参数(ClassX(a, **kwargs)ClassX(**kwargs)ClassX(b, **kwargs)。我想创建一个实例化类列表。现在我按顺序遍历每个创作。

有没有办法有效地使用列表理解来使这个更清洁?例如,除了a之外,可能还要创建一个类对象列表并注释那些需要正式参数(b**kwargs)的对象?即循环过来:

[ClassA: (None, None), ClassB: (fnA, None), ClassC: (None, fnB)]实现创建:

listOfClasses.append(ClassA(**kwargs))

listOfClasses.append(ClassB(**kwargs, a=fnA))

listOfClasses.append(ClassC(**kwargs, b=fnB))

我问的原因是因为在我的情况下我需要创建20-30个不同的类并按顺序附加到列表中。

为了更好地说明,我现在使用的确切代码如下:

def method(self, **kwargs):
    chain = []
    chain.append(ClassA(**kwargs))
    chain.append(ClassB(**kwargs))
    chain.append(ClassC(a=static_method_x, **kwargs))
    chain.append(ClassD(b=static_method_y, **kwargs))
    chain.append(ClassE(**kwargs))
    chain.append(ClassF(a=static_method_z, **kwargs))
    ...

因此每个实例都遵循三种类型之一,但**kwargs始终相同。 ab的值在它们是需要它们的类时会有所不同,并且与我班级中的其他静态方法相对应。我想知道是否有办法通过列表理解使用预定义的顺序类列表和相应的参数来使这个更清晰。

1 个答案:

答案 0 :(得分:0)

如果你创建一个列表元组,每个元组包含要与额外参数一起实例化的类,你可以使用列表推导来实例化每个元素,并合并kwargs和额外的args。

def method(self, **kwargs):
    to_instantiate = [
        # (Class, extra_args)
        (ClassA, {}),
        (ClassB, {}),
        (ClassC, {'a': static_method_x})
        (ClassD, {'b': static_method_y})
        (ClassE, {})
        (ClassF, {'a': static_method_z})
    ]
    chain = [C(**{**kwargs, **extra_args}) for C, extra_args in to_instantiate]

**{**kwargs, **extra_args}部分意味着创建一个包含kwargsextra_args中所有条目的新字典,然后将其解构为参数,就像之前使用**kwargs一样。请注意,此语法是在python 3.5中引入的。 See this question如果你想更好地理解它,并且还有旧的python版本的解决方案。

老实说,虽然我认为这段代码比你拥有的代码更难以理解。你写的代码可能有点冗长,但我认为它更容易阅读。