Joo*_*ost 3 python constructor
我有一个需要 5 个配置参数的对象,如下所示;
class A(object):
def __init__(self, a=1, b=2, c=3, d=4, e=4):
self.a = a
self.b = b
self.c = c
self.d = d
self.e = e
Run Code Online (Sandbox Code Playgroud)
但是,我想提供几组默认配置,而不仅仅是一组,例如(1, 2, 1, 2, 1)和(5, 4, 3, 2, 1),并且最好给它们提供合理的名称。最Pythonic 的方法是什么?我考虑过的一些选项是@classmethod生成实例的选项,或配置实例的实例方法。
我将有一个映射到预设配置字典的类方法:
class A(object):
CONFIGS = {
'default': {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 4},
...
}
def __init__(self, a, b, c, d, e):
...
@classmethod
def from_config(cls, config='default'):
if config not in cls.CONFIGS:
raise ValueError('invalid config: {!r}'.format(config))
return cls(**cls.CONFIGS[config])
Run Code Online (Sandbox Code Playgroud)
然后可以轻松扩展到任意数量的配置,并且可以使用以下方式创建实例:
a = A.from_config(config_name)
Run Code Online (Sandbox Code Playgroud)
您仍然可以为 提供默认参数值__init__,但将它们排除在外意味着如果用户尝试使用A()而不是A.from_config(); ,则会出现错误。这是否是一件好事取决于你,但我认为让用户一致使用或from_config显式自定义参数是有好处的。
子类可以简单地定义自己的CONFIGS字典并使用继承的from_config甚至可能的__init__.
就其他选项而言:
__init__采用参数或配置名称的方法会过于复杂且容易出错;和a = A().configure(config_name),where configurewill return self),但是类方法更清楚地表明应该设置配置在创建时并且没有改变。该功能非常简单,您可以将其提取到混合类中以便在其他地方重用:
class Configurable(object):
"""Mix-in for creating instances from preset configs."""
CONFIGS = {}
@classmethod
def from_config(cls, config):
if config not in cls.CONFIGS:
raise ValueError('invalid config: {!r}'.format(config))
args, kwargs = cls.CONFIGS[config]
return cls(*args, **kwargs)
class A(Configurable, ...): # can still include any other inheritance
CONFIGS = {
'default': ((), {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 4}),
...
}
def __init__(self, a, b, c, d, e):
...
@classmethod
def from_config(cls, config='default'):
return super(A, cls).from_config(config)
Run Code Online (Sandbox Code Playgroud)
请注意,为了尽可能广泛地重用,我现在单独提供了positionalargs和named kwargs,并删除了default config。