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

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.


When you do this:

super(MyFoo, self).__init__(*args, **kwargs)

It is the same as if you did this, base on how your code is working:

super(MyFoo, self).__init__("python", 2.7, stack="overflow")

However, the __init__ function of Foo (from which MyFoo inherits) doesn't support a keyword argument named "stack".


The reason is all the arguments are already unpacked into kwargs and it is a dict now. and you are trying to pass it to a normal variables.

def bun(args,kwargs):
print 'i am here'
print kwargs

def fun(*args,**kwargs):
print kwargs
bun(*args,**kwargs)

 fun(hill=3,bi=9) # will fail.


def bun(*args,**kwargs):
print 'i am here'
print kwargs

def fun(*args,**kwargs):
print kwargs
bun(*args,**kwargs) # will work.



fun(hill=3,bi=9)

Try making the modification at

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'

should work..!

Tags:

Python