I'd like to get idea why should I use kwargs or args over passing in a simple dict (or tuple in case of args)?
I wrote a very simple code snippet to check what exactly happens and I can't find any pros to use kwargs over a dict. If anyone could tell me why should I use those I'd be happy. Now as I can see it just more pythonic but don't makes any difference. Also if you use a simple dict then it's more readable because all the languages can do that but not the kwargs way.
def test_normal(input: dict):
for element in input.items():
print('Type: {}, raw: {}'.format(type(input), input))
print('key: {}, value: {}'.format(element[0], element[1]))
def test_kwargs(**kwargs):
for element in kwargs.items():
print('Type: {}, raw: {}'.format(type(kwargs), kwargs))
print('key: {}, value: {}'.format(element[0], element[1]))
test_normal(dict(name='Joseph'))
test_kwargs(name='Joseph')
Type: <class 'dict'>, raw: {'name': 'Joseph'}
key: name, value: Joseph
Type: <class 'dict'>, raw: {'name': 'Joseph'}
key: name, value: Joseph
These are different things and both have their use-cases. Just a rule of thumb: If it looks like a function parameter, it should be a function parameter.
There are several neat use-cases for *args
and **kwargs
. One of which is passing through parameters that you don't care about at this point:
Say you have class Base
and class A
inherited from Base
:
class Base:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
class A(Base):
def __init__(self, n, *args, **kwargs):
super().__init__(*args, **kwargs)
self.n = n
As you see class A
does not care about Base
's __init__
parameters, so it just passes everything (except n
that it needs) forward. So if you were to change Base
's __init__
you would not need to change A
.
But when you create A
object you would pass parameters normally:
a = A(5, 3, y=6, z=42)
A similar idea is when you implement a decorator which you'd like to use on a function with any kind and number of arguments:
def say_hello_first(fn):
def wrapper(*args, *kwargs):
print('Hello')
return fn(*args, **kwargs)
return wrapper
@say_hello_first
def foo(x):
print(x)
@say_hello_first
def bar(a, b, c=3.14):
print((a + b) * c)
then:
>>> foo(42)
Hello
42
>>> bar(1, 2, c=3)
Hello
9
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