Why does {'kwargs':{'1':'a', '2':'b'}}
appear when I run test_func()
?
I would have expected just this to print: {'1':'a', '2':'b'}
.
Code:
class MyClass:
def __init__(self, **kwargs):
self.kwargs = kwargs
def test_func(self):
print(self.kwargs)
test_kwargs = {'1':'a', '2':'b'}
my_class = MyClass(kwargs=test_kwargs)
my_class.test_func()
Ouput:
{'kwargs': {'1': 'a', '2': 'b'}}
It's because you initialize the instance by passing 1 keyword argument named kwargs
with the dictionary as value.
If you want to see the dictionary as kwargs, you need to call in using my_class = MyClass(**test_kwargs)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With