django, python

Usage of *args and **kwargs in Python, extra example in Django

What are *args and **kwargs in python?

While defining the functions sometimes we also specify parameters which we will use these parameters when we call these functions.

Sometimes we don’t know the number of parameters of functions, in these cases, we use *args and **kwargs. Basically *args and **kwargs allow us to pass multiple arguments or keyword arguments to a function.

First, let’s look at the usage of *args

def my_func(name, *args):
    print(name, args)


my_func('Alex', 'Bob', 'Danny')

#output
#Alex ('Bob', 'Danny')

 

Now let’s try passing keyword argument but without *kwargs. We got an error.

def my_func(name, *args):
    print(name, args)


my_func('Alex', 'Bob', 'Danny', other_name='XXXX')

# output
# Traceback (most recent call last):
#   File "args_kwargs.py", line 5, in <module>
#     my_func('Alex', 'Bob', 'Danny', other_name='XXXX')
# TypeError: my_func() got an unexpected keyword argument 'other_name'

 

We can fix it by passing this key as None or default value.

def my_func(name, *args, other_name=None):
    print(name, args, other_name)


my_func('Alex', 'Bob', 'Danny', other_name='XXXX')

# output
# Alex ('Bob', 'Danny') XXXX

 

Ok, what about we will try to add another one. Because it is accepting a single key. Let’s check.

def my_func(name, *args, other_name=None):
    print(name, args, other_name)


my_func('Alex', 'Bob', 'Danny', other_name='XXXX', other_name2='YYYY')

# output
# Traceback (most recent call last):
#   File "args_kwargs.py", line 5, in <module>
#     my_func('Alex', 'Bob', 'Danny', other_name='XXXX', other_name2='YYYY')
# TypeError: my_func() got an unexpected keyword argument 'other_name2'

Let’s now add **kwargs and then try

def my_func(name, *args, **kwargs):
    print(name, args, kwargs)


my_func('Alex', 'Bob', 'Danny', other_name='XXXX', other_name2='YYYY')

# output
# Alex ('Bob', 'Danny') {'other_name': 'XXXX', 'other_name2': 'YYYY'}

By default, **kwargs is an empty dictionary. Each undefined keyword argument is stored as a key-value pair in the **kwargs dictionary.

Bob is the first positional argument, Bob and Danny are non-keyworded variable-length argument lists, and XXXX, YYYY is keyworded variable-length argument dictionary.

In practice argument’s ordering are like below:

  • Formal positional arguments,
  • *args
  • Keyword arguments
  • **kwargs

Please note that positional arguments come first and then keyword arguments follow.

For example:

def my_func(name, *args, other_name=None, **kwargs):
    print(name, args, other_name, kwargs)


my_func('Alex', 'Bob', 'Danny', other_name='XXXX', other_name1='YYYY', other_name2='ZZZZ')

# output
# Alex ('Bob', 'Danny') XXXX {'other_name1': 'YYYY', 'other_name2': 'ZZZZ'}

 

At the end let’s look at the usage of *args and **kwargs in Django

consider you have a view like below:

def get_book(request, **kwargs):
    template_name = 'books.html'
    books = Books.objects.filter(id=kwargs.get('id'))
    context = {'books': books}

    render(request, template_name, context=context)

# urls.py
# path('book/<int:id>', get_book, name="get_book"),

 

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *