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..!