Why can't pass *args and **kwargs in __init__ of a child class

python

Solution

Your `Foo.__init__()` does not support arbitrary keyword arguments. You can add `**kw` to it's signature to make it accept them:

class Foo(object):
    def __init__(self, value1, value2, **kw):
       print 'I think something is being called here'
       print value1, value2, kw

Keyword parameters are matched only with arguments with exact matching keyword names; your `Foo` method would need to have `Python` and `stack` keyword parameters. If no matching keyword parameter are found but a `**kw` parameter is, they are collected in that parameter instead.

If your subclass knows that the parent class only has positional arguments, you can always pass in positionals:

class MyFoo(Foo):
    def __init__(self, *args, **kwargs):
    # do something else, don't care about the args
        print args, kwargs
        while len(args) < 2:
            args += kwargs.popitem()
        super(MyFoo, self).__init__(*args[:2])

where you now must pass in two or more arguments to `MyFoo` for the call to work.

In essence, `super().methodname` returns a reference to the bound method; from there on out it is a normal method, so you need to pass in arguments that any method can accept. If your method doesn't accept keyword arguments, you get an exception.

Problem

To understand *args and **kwargs I made some searchs about, when I fell on this question *args and **kwargs? The answer below the chosen answer caught my attention, which is this: ``` class Foo(object): def __init__(self, value1, value2): # do something with the values print value1, value2 class MyFoo(Foo): def __init__(self, *args, **kwargs): # do something else, don't care about the args print 'myfoo' super(MyFoo, self).__init__(*args, **kwargs) ``` I tried some things on this example and running the code this way: ``` class Foo(object): def __init__(self, value1, value2): # do something with the values print 'I think something is being called here' print value1, value2 class MyFoo(Foo): def __init__(self, *args, **kwargs): # do something else, don't care about the args print args, kwargs super(MyFoo, self).__init__(*args, **kwargs) foo = MyFoo('Python', 2.7, stack='overflow') ``` I got this: ``` [...] super(MyFoo, self).__init__(*args, **kwargs) TypeError: __init__() got an unexpected keyword argument 'stack' ``` Changing to be like `super(MyFoo, self).__init__(args, kwargs)` the results are: ``` ('Python', 2.7) {'stack': 'overflow'} I think something is being called here ('Python', 2.7) {'stack': 'overflow'} ``` For some blow mind reasons I'm questioning this: what could be right and wrong in the example above? What would be allowed to do and what wouldn't in real life production?

Original source

Related problems