类层次结构和构造函数是相关的。子类中的参数需要传递给它们的父类。
所以,在Python中,我们最终会得到类似的东西:
class Parent(object):
def __init__(self, a, b, c, ka=None, kb=None, kc=None):
# do something with a, b, c, ka, kb, kc
class Child(Parent):
def __init__(self, a, b, c, d, e, f, ka=None, kb=None, kc=None, kd=None, ke=None, kf=None):
super(Child, self).__init__(a, b, c, ka=ka, kb=kb, kc=kc)
# do something with d, e, f, kd, ke, kf
想象一下这有十几个子类和很多参数。添加新参数变得非常乏味。
当然可以完全省去命名参数并使用* args和** kwargs,但这会使方法声明变得模糊。
在Python(2.6)中是否有优雅处理这种模式的模式?
“优雅”我的意思是我想减少参数出现的次数。 a,b,c,ka,kb,kc都出现3次:在Child构造函数中,在对Parent的super()调用中,以及在Parent构造函数中。
理想情况下,我想为Parent的 init 指定一次参数,而在Child的 init 中只指定其他参数。
我想做这样的事情:
class Parent(object):
def __init__(self, a, b, c, ka=None, kb=None, kc=None):
print 'Parent: ', a, b, c, ka, kb, kc
class Child(Parent):
def __init__(self, d, e, f, kd='d', ke='e', kf='f', *args, **kwargs):
super(Child, self).__init__(*args, **kwargs)
print 'Child: ', d, e, f, kd, ke, kf
x = Child(1, 2, 3, 4, 5, 6, ka='a', kb='b', kc='c', kd='d', ke='e', kf='f')
遗憾的是,这不起作用,因为4,5,6最终被分配给kd,ke,kf。
是否有一些优雅的python模式来实现上述目标?
答案 0 :(得分:7)
我怀疑一点点重构可以剥离一些策略对象,这些对象可以简化这种层次结构并使超级复杂的构造函数消失。
答案 1 :(得分:2)
嗯,我能看到的唯一解决方案是使用列出的变量以及* args和** kwargs的混合,如下:
class Parent(object):
def __init__(self, a, b, c, ka=None, kb=None, kc=None):
pass
class Child(Parent):
def __init__(self, d, e, f, *args, kd=None, ke=None, kf=None, **kwargs):
Parent.__init__(self, *args, **kwargs)
pass
这样,您可以看到每个类需要哪些参数,但无需重新输入。
有一点需要注意的是,当你变成(d,e,f,a,b,c)时,你会失去你想要的顺序(a,b,c,d,e,f)。我不确定是否有办法在其他非命名参数之前使用* args。
答案 2 :(得分:1)
我尝试将参数分组到他们自己的对象中,例如,而不是传递 sourceDirectory,targetDirectory,temporaryDirectory,serverName,serverPort,我有一个 DirectoryContext和ServerContext对象。
如果上下文对象开始有更多 它可能导致here中提到的策略对象的行为或逻辑。