Defining a function with an arbitrary number of arguments

suggest change

Arbitrary number of positional arguments:

Defining a function capable of taking an arbitrary number of arguments can be done by prefixing one of the arguments with a \*

def func(*args):
    # args will be a tuple containing all values that are passed in
    for i in args:
        print(i)

func(1, 2, 3)  # Calling it with 3 arguments
# Out: 1
#      2
#      3

list_of_arg_values = [1, 2, 3]
func(*list_of_arg_values)  # Calling it with list of values, * expands the list
# Out: 1
#      2
#      3 

func()  # Calling it without arguments
# No Output

You can’t provide a default for args, for example func(*args=[1, 2, 3]) will raise a syntax error (won’t even compile).

You can’t provide these by name when calling the function, for example func(*args=[1, 2, 3]) will raise a TypeError.

But if you already have your arguments in an array (or any other Iterable), you can invoke your function like this: func(*my_stuff).

These arguments (*args) can be accessed by index, for example args[0] will return the first argument

Arbitrary number of keyword arguments

You can take an arbitrary number of arguments with a name by defining an argument in the definition with two \* in front of it:

def func(**kwargs):
    # kwargs will be a dictionary containing the names as keys and the values as values
    for name, value in kwargs.items():
        print(name, value)

func(value1=1, value2=2, value3=3)   # Calling it with 3 arguments
# Out: value1 1
#      value2 2
#      value3 3

func()                               # Calling it without arguments
# No Out put

my_dict = {'foo': 1, 'bar': 2}
func(**my_dict)                      # Calling it with a dictionary
# Out: foo 1
#      bar 2

You can’t provide these without names, for example func(1, 2, 3) will raise a TypeError.

kwargs is a plain native python dictionary. For example, args['value1'] will give the value for argument value1. Be sure to check beforehand that there is such an argument or a KeyError will be raised.

Warning

You can mix these with other optional and required arguments but the order inside the definition matters.

The positional/keyword arguments come first. (Required arguments).

Then comes the arbitrary *arg arguments. (Optional).

Then keyword-only arguments come next. (Required).

Finally the arbitrary keyword **kwargs come. (Optional).

#       |-positional-|-optional-|---keyword-only--|-optional-|
def func(arg1, arg2=10 , *args, kwarg1, kwarg2=2, **kwargs):
     pass

Python 2.x doesn’t support keyword-only parameters. This behavior can be emulated with kwargs:

def func(arg1, arg2=10, **kwargs):
    try:
        kwarg1 = kwargs.pop("kwarg1")
    except KeyError:
        raise TypeError("missing required keyword-only argument: 'kwarg1'")

    kwarg2 = kwargs.pop("kwarg2", 2)
    # function body ...

Note on Naming

The convention of naming optional positional arguments args and optional keyword arguments kwargs is just a convention you can use any names you like but it is useful to follow the convention so that others know what you are doing, or even yourself later so please do.

Note on Uniqueness

Any function can be defined with none or one *args and none or one **kwargs but not with more than one of each. Also *args must be the last positional argument and **kwargs must be the last parameter. Attempting to use more than one of either will result in a Syntax Error exception.

Note on Nesting Functions with Optional Arguments

It is possible to nest such functions and the usual convention is to remove the items that the code has already handled but if you are passing down the parameters you need to pass optional positional args with a \* prefix and optional keyword args with a ** prefix, otherwise args with be passed as a list or tuple and kwargs as a single dictionary. e.g.:

def fn(**kwargs):
    print(kwargs)
    f1(**kwargs)

def f1(**kwargs):
    print(len(kwargs))

fn(a=1, b=2)
# Out:
# {'a': 1, 'b': 2}
# 2

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:



Table Of Contents