How to add a named keyword argument to a function signature
<p>Can I use a mixin class to add a named keyword to the signature of a function in the base? At the moment I can't work out how to avoid overwriting the base function's signature:</p>

<pre><code>from inspect import signature

class Base(object):
    def __init__(self, foo='bar', **kwargs):
        pass

class Mixin(base):
    def __init__(self, foo2='bar2', **kwargs):
        super(Mixin, self).__init__(**kwargs)

class P(Mixin, Base):
    pass

print(signature(P.__init__))


# Output: (self, foo2='bar2', **kwargs)

$ Desired output: (self, foo1='bar1', foo2='bar2', **kwargs)
</code></pre>

<p><strong>Edit</strong> Thanks for the answers so far, unfortunately I actually need to add the named parameter to the function signature, while also keeping the named parameters from the original base function signature (and these will vary depending on the base). The reason is that the <a href="https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/base.py#L207" rel="nofollow"><code>signature</code> is used elsewhere for intraspection to extract the parameter names.</a>: Is this going to be possible in the <code>__init__</code> method?</p>

<p>Here is a (horrible) partial solution, which changes the signature on instances, but not on the class itself, also it's missing <code>**kwargs</code> for some reason:</p>

<pre><code>class Mixin(Base):
     def __init__(self, foo2='bar2', **kwargs):
         super(Mixin, self).__init__(**kwargs)
         sig = signature(super(Mixin, self).__init__)
         params = {k:v.default for k,v in sig.parameters.items() if v.default != _empty}
         params['foo2'] = 'bar2'
         argstring = ",".join("{}='{}'".format(k,v) for k,v in params.items())
         exec("def new_init({}, **kwargs): self.__init__(**kwargs)".format(argstring))
         self.__init__ = new_init


class P(Mixin, Base):
    pass

p = P()
print(signature(p.__init__))
# (foo2='bar2', foo='bar')
</code></pre>

<p>When subclassing, you can either extend or override the methods of the superclass, but you can't* modify them directly. Overiding is achieved by simply writing a new method of the same name; extension is achieved by overriding the method and then calling the superclass's method as a part of your replacement.</p>

<p>Here are two classes, the second of which overrides one method and extends another:</p>

<pre><code>class A:
    def method1(self):
        print("Method A.1 called")
    def method2(self, arg1):
        print("Method A.2 called with argument", arg1)

class B(A):
    def method1(self):
        print("Method B.1 called")
    def method2(self, arg1, arg2="keyword arg"):
        print("Method B.1 called with arg1=", arg1, "arg2=", arg2)
        super().method2(arg1)
        print("Extended method complete")
</code></pre>

<p>Using this in an interactive context we see the following:</p>

<pre><code>&gt;&gt;&gt; b = B()
&gt;&gt;&gt; b.method1()
Method B.1 called
&gt;&gt;&gt; b.method2("first", arg2="second")
Method B.1 called with arg1= first arg2= second
Method A.2 called with argument first
Extended method complete
</code></pre>

<p>* Technically it's possible in Python, but the code would be ugly and anyway any changes to the superclass would be seen by everything that <em>used</em> the superclass.</p>

python oop