Constructor specialization in python

Class hierarchies and constructors are interconnected. Parameters from the child class must be passed to their parents.

So, in Python we get something like this:

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 

Imagine this with a dozen child classes and lots of options. Adding new parameters becomes very tedious.

Of course, you can completely abandon named parameters and use * args and ** kwargs, but this makes the method declarations ambiguous.

Is there a template for elegantly solving this issue in Python (2.6)?

By "elegant" is meant that I would like to reduce the number of times that parameters appear. a, b, c, ka, kb, kc appear 3 times: in the Child constructor, in the super () call for the parent, and in the parent constructor.

Ideally, I would like to specify the parameters for the parent init once, and in Child init, specify only additional parameters.

I would like to do something like this:

 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') 

This, unfortunately, does not work, since 4, 5, 6 are eventually assigned kd, ke, kf.

Is there some kind of elegant python template to accomplish the above?

+4
source share
3 answers

“a dozen child classes and a lot of parameters” sounds like a problem, regardless of the parameter naming.

I suspect that a little refactoring may clear some Strategy objects that would simplify this hierarchy and remove supercomplex constructors.

+6
source

Well, the only solution I could see was to use a mixture of the variables listed, as well as * args and ** kwargs, as such:

 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 

Thus, you can see what parameters are required for each of the classes, but without the need to re-enter them.

It should be noted that you lose the desired order (a, b, c, d, e, f) when it becomes (d, e, f, a, b, c). I'm not sure if there is a way to have * args before other unnamed parameters.

+2
source

I'm trying to group the parameters into my own objects, for example, instead of passing sourceDirectory, targetDirectory, temporary directory, serverName, serverPort, I will have DirectoryContext and ServerContext Objects.

If context objects begin to have more behavior or logic, this can lead to the strategy objects mentioned in here .

+1
source

All Articles