More arguments in derived class __init__ than base class __init__
<p>How can I extend the <code>__init__</code> of a base class, <strong>add more arguments to be parsed</strong>, without requiring <code>super().__init__(foo, bar)</code> in every derived class?</p>

<pre class="lang-python prettyprint-override"><code>class Ipsum:
    """ A base ipsum instance. """

    def __init__(self, foo, bar):
        self.foo = flonk(foo)
        grungole(self, bar)
        self._baz = make_the_baz()


class LoremIpsum(Ipsum):
    """ A more refined ipsum that also lorems. """

    def __init__(self, foo, bar, dolor, sit, amet):
        super().__init__(foo, bar)
        farnark(sit, self, amet)
        self.wibble(dolor)
</code></pre>

<p>The purpose of the example is to show that there is significant processing happening in the <code>Ipsum.__init__</code>, so it should not be duplicated in every sub-class; and the <code>LoremIpsum.__init__</code> needs the <code>foo</code> and <code>bar</code> parameters processed exactly the same as <code>Ipsum</code>, but also has its own special parameters.</p>

<p>It also shows that, if <code>Ipsum</code> needs to be modified to accept a different signature, <em>every derived class</em> also needs to change not only its signature, but how it calls the superclass <code>__init__</code>. That's unacceptably fragile.</p>

<p>Instead, I'd like to do something like:</p>

<pre class="lang-python prettyprint-override"><code>class Ipsum:
    """ A base ipsum instance. """

    def __init__(self, foo, bar, **kwargs):
        self.foo = flonk(foo)
        grungole(self, bar)
        self._baz = make_the_baz()

        self.parse_init_kwargs(kwargs)

    def parse_init_kwargs(self, kwargs):
        """ Parse the remaining kwargs to `__init__`. """
        pass


class LoremIpsum(Ipsum):
    """ A more refined ipsum that also lorems. """

    def parse_init_kwargs(self, kwargs):
        (dolor, sit, amet) = (kwargs['dolor'], kwargs['sit'], kwargs['amet'])
        farnark(sit, self, amet)
        self.wibble(dolor)
</code></pre>

<p>That has the big advantage that <code>LoremIpsum</code> need <em>only</em> do the parts that are special to that class; handling <code>Ipsum</code> arguments is handled by that class's <code>__init__</code> without any extra code.</p>

<p>The disadvantage is obvious, though: this is effectively re-implementing the handling of named parameters by passing a dictionary around. It avoids a lot of repetition, but isn't very clear.</p>

<p>What tools are available to avoid the sub-class definitions <em>always</em> needing to declare the <code>foo</code> and <code>bar</code> parameters, and <em>always</em> needing to call <code>super().__init__(foo, bar)</code>? Those are easy to get wrong, so it would be better if they weren't needed and could <strong>just automatically happen</strong>, while still allowing <code>LoremIpsum</code>'s customisation of the initialisation.</p>

<p>Derived classes need to call the superclass <code>__init__</code>.  That's how object-oriented programming works.  Is it brittle?  Yes, it can be; that's why deep or broad class hierarchies aren't usually a good idea.  If the operations on <code>foo</code> and <code>bar</code> in <code>Lorem</code> are significant (as you say they are), then correctly invoking <code>Lorem.__init__()</code> is a cost that must be paid.
Default values for <code>foo</code> and <code>bar</code> (and any new parameters) are the only tool I can think of that might make change the amount of textual change needed, but default values aren't always appropriate, so that mitigation might not apply.</p>

python inheritance