*args and **kwargs in Python

Difference Between *args and **kwargs

When you write functions in Python, sometimes you don’t know beforehand how many arguments (inputs) the function will receive. *args and **kwargs help you handle such situations.

  • *args lets a function accept any number of positional arguments (arguments without a name).
  • **kwargs lets a function accept any number of keyword arguments (arguments with a name).

Using *args and **kwargs makes your functions more flexible and reusable.

args and kwargs in Python

What is Python *args?

*args allows a function to take more positional arguments than you initially specified. The name *args is just a convention; you can name it anything, but *args is widely used and recommended for readability.

Syntax of Python *args

Here’s how you use *args in a function:

python
1def my_function(*args):
2    for arg in args:
3        print(arg)
  • def my_function(*args): This defines a function named my_function that takes any number of positional arguments.
  • args: Inside the function, args is treated as a tuple (a collection of items) containing all the extra arguments passed to the function.

Example

Let’s see *args in action with an example:

python
1def greet(*args):
2    for name in args:
3        print(f"Hello, {name}!")
4
5greet("Alice", "Bob", "Charlie")

Output:

bash
1Hello, Alice!
2Hello, Bob!
3Hello, Charlie!

Explanation:

  • The greet function can accept any number of names.
  • Each name passed to the function is printed with a greeting.
  • You can pass as many names as you want without changing the function.

What is Python **kwargs?

While *args handles extra positional arguments, **kwargs handles extra keyword arguments. **kwargs allows you to pass a variable number of named arguments to a function.

Syntax of Python **kwargs

Here’s how you use **kwargs in a function:

python
1def my_function(**kwargs):
2    for key, value in kwargs.items():
3        print(f"{key}: {value}")
  • def my_function(**kwargs): This defines a function named my_function that takes any number of keyword arguments.
  • kwargs: Inside the function, kwargs is treated as a dictionary (a collection of key-value pairs) containing all the extra keyword arguments passed to the function.

Example

Let’s see **kwargs in action with an example:

python
1def display_info(**kwargs):
2    for key, value in kwargs.items():
3        print(f"{key}: {value}")
4
5display_info(name="Alice", age=30, city="New York")

Output:

1name: Alice
2age: 30
3city: New York

Explanation:

  • The display_info function can accept any number of named arguments.
  • Each key-value pair passed to the function is printed.

*args and **kwargs in Python to Call a Function

You can use both *args and **kwargs in a single function to handle both positional and keyword arguments at the same time. This makes your function even more flexible.

Example

Here’s an example of a function that uses both *args and **kwargs:

python
1def combined_example(*args, **kwargs):
2    print("Positional arguments:", args)
3    print("Keyword arguments:", kwargs)
4
5combined_example(1, 2, 3, name="Alice", age=30)

Output:

bash
1Positional arguments: (1, 2, 3)
2Keyword arguments: {'name': 'Alice', 'age': 30}

Explanation:

  • The combined_example function accepts both extra positional and keyword arguments.
  • It prints out the positional arguments as a tuple and the keyword arguments as a dictionary.

Best Practices

Using *args and **kwargs can make your code powerful, but it’s important to use them wisely. Here are some best practices to follow:

1. Use Clear and Descriptive Names

While *args and **kwargs are common names, you can use more descriptive names if it makes your code easier to understand.

python
1def process_items(*items, **item_details):
2    for item in items:
3        print(item)
4    for key, value in item_details.items():
5        print(f"{key}: {value}")

2. Document Your Functions

Always explain what your function does and how it uses *args and **kwargs. This helps others (and yourself) understand your code later.

python
1def create_user(username, *args, **kwargs):
2    """
3    Creates a new user.
4
5    :param username: The username of the new user.
6    :param args: Additional positional arguments.
7    :param kwargs: Additional keyword arguments like email, age, etc.
8    """
9    pass

3. Validate the Arguments

Even though *args and **kwargs are flexible, sometimes you need to check if the arguments passed meet certain criteria.

python
1def calculate_total(*args, discount=0):
2    if not all(isinstance(arg, (int, float)) for arg in args):
3        raise ValueError("All positional arguments must be numbers.")
4    total = sum(args) - discount
5    return total

4. Don’t Overuse *args and **kwargs

While they are useful, using too many *args and **kwargs can make your code hard to read. Use them only when necessary.

5. Order Matters in Function Definitions

When defining a function, place *args before **kwargs. Also, if you have regular parameters, they should come before *args and **kwargs.

python
1def example_function(a, b=2, *args, c=3, **kwargs):
2    pass

6. Use Type Hinting

Adding type hints can make your code clearer and help tools understand your code better.

python
1from typing import Any
2
3def display_info(*args: Any, **kwargs: Any) -> None:
4    pass

Conclusion

*args and **kwargs is used for writing flexible and efficient Python functions. These functions allow you to accept numbers of arguments, making your code more adaptable to different situations.

By following the best practices, you can use *args and **kwargs effectively without making your code confusing. Practice using them in your projects to become more comfortable and to make your Python programming more powerful.

Frequently Asked Questions

Related Articles

Sign-in First to Add Comment

Leave a comment 💬

All Comments

No comments yet.