在OO程序的初始化期间处理大量参数的大多数pythonic方法

问题描述:

考虑一个由具有不同类实例的实例化的容器实例构成的结构,其中应该可以通过配置文件来配置,例如,以字典的形式。什么是分配所有参数的pythonic方式?在OO程序的初始化期间处理大量参数的大多数pythonic方法

我能想到以下2个选项。哪个更pythonic,为什么?最常见的方法是pythonic,为什么?

选项1a,我目前的方法。每个包含实例都有kwargs:

# hundred parameters 
params = {'A_param_1':0,'B_param_1':0,...} 

class Container(): 
    def __init__(self,params): 

    self.InstanceA = self.ClassA(**params) 
    self.InstanceB = self.ClassB(**params) 
    ... 
    self.InstanceF = self.ClassF(**params) 

class ClassA(): 
    def __init__(self, 
        A_param_1=0, 
        ... 
        A_param_16=0.123, 
        **kwargs) 
    # set param values to self. 
    self._A_param_1 = A_param_1 

可能性1b,相同的,但更详细的无** PARAMS:

class Container(): 
    def __init__(self,params): 

    self.InstanceA = self.ClassA(all written out..) 
    self.InstanceB = self.ClassB(all written out..) 
    ... 
    self.InstanceF = self.ClassF(all written out..) 

选择2 - 同事的做法。每个包含实例确实没有kwargs:

# hundred parameters 
params = {'A_param_1':0,'B_param_1':0,...} 

class Container(): 
    def __init__(self,params): 

    self.InstanceA = self.ClassA(params) 
    self.InstanceB = self.ClassB(params) 
    ... 
    self.InstanceF = self.ClassF(params) 

class ClassA(): 
    def __init__(self, 
        params 
       ) 
    # set param values to self. 
    self._A_param_1 = self.params['A_param_1'] 

优点选项1A:每一个构造函数的默认值kwargs使得这些kwargs的性质明确的,从字面上。

缺点选项1a:一个不知道是使用默认值还是通过** params给出的值。 ** params抛出所有参数,而不仅仅是特定实例的参数。

优点选项2:如果没有提供特定的参数,每个实例都会以明确的方式捕获它所需要的关键错误。

缺点选项2:参数的典型值必须在文档字符串或注释中明确表示。

选项1b似乎结合了选项1a和选项2的风味与在构造函数调用中不得不显式解压** params的附加困难。

重复我的问题:总体而言,什么是最pythonic的方式来解决这个问题? PS:我希望我能让自己理解并用一些正确的术语来表达自己。如果没有,请让我知道。

+0

可能的重复https://*.com/questions/1389180/python-automatically-initialize-instance-variables –

我不喜欢将所有参数传递给每个构造函数。我会使用嵌套的字典是这样,可能存储在一个JSON文件的配置:

# hundred parameters 
params = {'A': {'A_param_1': 0, ..., 'A_param_16': 1}, 
      'B': {'B_param_1': 0, ...}, 
      ... 
      'F': {'F_param_1': 0, ...}} 

class Container(): 
    def __init__(self, params): 
     self.InstanceA = ClassA(**params['A']) 
     self.InstanceB = ClassB(**params['B']) 
     ... 
     self.InstanceF = ClassF(**params['C']) 

class ClassA: 
    def __init__(self, 
       A_param_1=0, 
       ... 
       A_param_16=0.123): 
     # set param values to self. 
     self._A_param_1 = A_param_1 

我也可能会通过计算这样的类名和实例名称自动化容器初始化:

class ClassF: 
    def __init__(self, foo): 
     self.foo = foo 

def main(): 
    c = 'F' 
    n = 23 
    cls = globals()['Class' + c] 
    o = cls(n) 
    print(o.foo) # => 23 

main() 

您可以使用setattr()作为self.InstanceA