Python *args and **kwargs
Python has a special syntax, *
(single asterisk) and **
(double asterisks), that lets you pass a variable number of arguments to a function. By convention, these are written as *args
and **kwargs
, but only the asterisks are important; you could equally write *vars
and **vars
to achieve the same result.
*args
is used to pass a non-keyworded variable-length argument list to your function. **kwargs
lets you pass a keyworded variable-length of arguments to your function.
Python functions
In a traditional Python function, you must explicitly define the number of arguments and parameters.
def func_one(x):
print(x)
func_one(5)
# 5
But what if the number of parameters does not match the number of arguments? For example, if we define one parameter but pass in none we get an error:
func_one()
# func_one() missing 1 required positional argument: 'x'
And if we pass in two arguments but only define one parameter we have another error:
func_one(5, 10)
# TypeError: func_one() takes 1 positional argument but 2 were given
In Python a function only works if the number of arguments matches the number of parameters.
*args example
By using *args
we can attach a variable-length number of arguments into our function.
For example:
def func_var_args(*args):
print(args)
func_var_args(1, 2, '3')
# (1, 2, '3')
This is useful when we don’t know in advance how many arguments we need to pass in.
**kwargs example
If we want to pass a keyworded variable length of arguments to a function, we use **kwargs
. It lets us handle named arguments in our function.
As an example:
def func_keyword_arg(**kwargs):
print(kwargs)
func_keyword_arg(keyword1=10, keyword2='foo')
# {'keyword2': 'foo', 'keyword1': 10}
If we wanted to return just the key/value we can use the items() method.
def func_keyword_arg_dict(**kwargs):
for key, value in kwargs.items():
print(key,":",value)
func_keyword_arg_dict(keyword1=10, keyword2='foo')
# ('keyword2', ':', 'foo')
# ('keyword1', ':', 10)
*args and **kwargs together
Often *args
and **kwargs
are used together in a function where we have at least one required argument. In these instances, order matters. Positional-only parameters must come first, so ``args and
**kwargs` are placed *after any required arguments.
def one_required_arg(required_arg, *args, **kwargs):
print(required_arg)
if args:
print(args)
if kwargs:
print(kwargs)
All three of the following will work with this function:
func("required argument")
func("required argument", 1, 2, '3')
func("required argument", 1, 2, '3', keyword1=4, keyword2="foo")
Final thoughts
*args
and **kwargs
are powerful Python features that can make writing functions a much more enjoyable task. They are also common when extending an existing method in a subclass.
Just remember, normal, positional-only parameters come first. A simple way to remember this is always add *args
and **kwargs
at the end of your required arguments.
So if we have one required argument, write:
def some_func(required_arg, *args, **kwargs):
pass
If there are two required arguments:
def some_func(required_arg1, required_arg2, *args, **kwargs):
pass
And so on!
Want to improve your Python? I have a list of recommended Python books.