Arrr-g Matey! Sailing the Code Seas with Args and Kwargs: A Pirate's Guide to Function Adventure!

·

5 min read

In Python, we have two handy ways to pass arguments to functions: args and kwargs. Args is like a basket where you can put any number of arguments without naming them, while kwargs is like a basket where you can put named arguments. We use them when we are not sure how many arguments we need to pass to a function.

Args

As noted, the special syntax *args in Python function definitions is used to pass a variable number of arguments to a function. This allows you to pass a list of positional arguments of any length without specifying their names explicitly

Example 1

First, let's create a simple function where we shall just add two numbers together.

This is a simple function that I think is self-explanatory. To understand more about functions, see my article here: https://hashnode.com/post/clrwfyk9k00050al1gdia1leo

Suppose you want to modify the add function to accept a variable number of arguments. In the provided example, let's attempt to call the add function with three arguments:

The add function is defined to only accept two arguments (a and b). When you try to pass three arguments (5, 5, 5), Python raises an error because the function is not designed to handle this situation.

To address this issue, you can utilize the *args parameter, which allows the function to accept any number of positional arguments. Let's modify the add function to achieve this:

By using *args, you can pass any number of arguments to the add function, and it will sum them up correctly. In this case, it will output 15 since it adds up all the arguments provided (5 + 5 + 5). This approach aligns with the concept of Python's *args, which liberates one from the conventional practice of confining oneself to a predetermined number of positional arguments.

Example 2

It is possible to think that you have to name your args variable the same as args, but this is not true. You can name the variable anything you like, as long as you precede it with a single asterisk (*). This is shown in the example below:

  1. First, we define function named accomplishments_of_wilberforce

  2. The *wilberforce parameter allows the function to accept any number of positional arguments. These arguments will be collected into a tuple named wilberforce

  3. The : str annotation suggests that the arguments should be strings

  4. The -> None part indicates that this function does not return a value

  5. The for loop function iterates over each item in the wilberforce tuple

  6. For each item in the tuple, it prints the item (accomplishment)

  7. Call the accomplishments_of_wilberforce function with four string arguments

  8. These arguments/accomplishments are packed into the wilberforce tuple inside the function

  9. Finally, the function is called, it will print each accomplishment on a new line

Kwargs

The special syntax **kwargs is utilized to pass a variable-length argument list consisting of keyworded arguments. Unlike *args, which captures non-keyworded arguments into a tuple, **kwargs employs the double star to facilitate the passing of keyword arguments, allowing for any number of them. These keyword arguments are collected into a dictionary named kwargs (or any other specified name), where each argument becomes a key-value pair. Thus, while *args collects positional arguments, **kwargs enables the handling of keyword arguments in a dictionary format.

Example 1

Before we delve into the code, I want to clarify that it's not strictly necessary to include Union[str, int] in the **kwargs syntax or specify -> None to indicate that the function does not return anything, or even import Union from typing. Omitting these would not affect the functionality of the code; it's simply a matter of personal preference. However, I prefer to include type hints and specify the return type for clarity and consistency in my code.

  1. First, let us define a function named user_details that accepts keyword arguments (**kwargs)

  2. The Union[str, int] type hint specifies that the values of the keyword arguments can be either strings or integers

  3. Inside the function, it iterates over each key-value pair in the kwargs dictionary and prints them.

  4. When we call the function with the provided keyword arguments (name="Alice", age=30, city="New York"), it prints the details accordingly.

Example 2

  1. The function create_user_profile is defined with the **profile_details parameter, which indicates that it accepts any number of keyword arguments

  2. The type hint Union[str, int] specifies that the values of the keyword arguments can be either strings or integers

  3. The return type hint -> dict indicates that the function returns a dictionary.

  4. Inside the function, a dictionary named profile is constructed to hold the user profile details

  5. The get() method is used to retrieve the value associated with each key in the profile_details dictionary. If a key is not found, a default value is provided (e.g., 'Guest' for 'username', 'Not provided' for 'email', and 'N/A' for 'first_name' and 'last_name')

  6. The constructed user profile dictionary profile is returned from the function

  7. The function create_user_profile is called with keyword arguments specifying various details of the user profile for "user1", such as 'username' and 'first_name'

  8. These details are passed to the function as keyword arguments

  9. The user profile dictionary user1 is printed to display the user profile details

And that concludes our exploration of the special *args and **kwargs syntax in Python. I trust that you, dear reader, have gained valuable insights from this discussion. In our next article, we'll delve into the world of Python user input and discover how it seamlessly integrates with the power of *args and **kwargs. Stay tuned for more exciting insights and practical tips. Until then, happy coding!