It's because **kwargs
automagically collects the remaining (unused) named arguments and puts them in a dictionary for you, much the same as *args
collects the unused unnamed (positional) arguments into a tuple(a).
It's meant to handle things like:
my_class = MyClass(a=1, b=2)
which is possibly what you were trying to do.
The way you've done it in the question will result in a dictionary with the key kwargs
referencing the dictionary because it will create a single dictionary keyed on the argument name kwargs
- that is exactly what you see.
(a) You can see this behaviour in the following transcript:
Python 3.9.0 (default, Oct 12 2020, 02:44:01)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def fn(one, two, *args, **kwargs):
... print(one)
... print(two)
... print(args)
... print(kwargs)
...
>>> fn(1, 2, 3, 4, 5, six=6, seven=7)
1
2
(3, 4, 5)
{'six': 6, 'seven': 7}
Keep in mind args
and kwargs
are conventions, not rules. You can use different names, it's the *
and **
that matter.