Skip to main content
Taught by Tech Leads

Master pipelines, cloud & AI to become an operational Data Engineer.

DataScientist.fr
Image de Understanding Python *args and **kwargs - Interactive Tutorial
Python

Understanding Python *args and **kwargs - Interactive Tutorial

Photo de Romain DE LA SOUCHÈRE

Tech Lead, CTO AXI Technologies

Published on 2 janvier 2025 · 9 min of reading

In the fascinating world of programming, the flexibility of functions is crucial for writing efficient and reusable code. Knowing how to pass multiple arguments to a function is an essential skill for any developer. This article invites you to explore the subtleties of the *args and **kwargs variables, powerful tools that allow you to manage an indefinite number of arguments. Discover how to optimize your functions by mastering these advanced techniques and understanding the importance of argument order and unpacking with the asterisk operators. Dive into this universe and transform your approach to development!

Passing multiple arguments to a function

Variadic arguments in Python offer great flexibility when defining functions, allowing you to pass a variable number of arguments. This feature is particularly useful when you do not know in advance how many values will be provided to a function.

Using *args

The first mechanism for passing multiple arguments to a function is the use of *args. This special parameter allows capturing an indefinite number of positional arguments. The arguments are packed into a tuple, making it easier to manipulate them.
Code example:
python
In this example, the add function can accept any number of arguments and add them using the built-in sum function.

Using **kwargs

Another powerful tool is **kwargs, which captures named arguments as a dictionary. This allows you to work with key-value pairs, providing great flexibility in managing data.
Code example:
python
In this example, the display_info function processes a variable number of named arguments, displaying them as a list.

Combining *args and **kwargs

It is also possible to combine *args and **kwargs in the same function, offering maximum flexibility. However, it is crucial to respect the order of parameters: first the positional arguments, then *args, and finally **kwargs.
Code example:
python
This code shows how to manage different types of arguments simultaneously, which is useful for creating robust and versatile functions.

Best practices

Using *args and **kwargs can bring a lot of flexibility, but it is important to remain clear and explicit about the use and intent of these arguments in your function documentation. This ensures that users of your functions understand how to call them correctly.
By incorporating these concepts into your Python projects, you can create more dynamic and adaptable functions capable of handling a variety of scenarios without compromising the readability and maintainability of your code.

Using the args variable in function definitions

The *args variable is a powerful tool in Python that allows developers to design functions capable of receiving an indeterminate number of positional arguments. This flexibility is particularly useful when you want to create generic functions that can be applied to various scenarios.

Definition and syntax of *args

When a function is defined with *args, all additional positional arguments passed to that function are collected into a tuple. This means you can access each individual argument using indices as you would with a list.
Code example:
python
In this example, display_elements can accept any number of arguments and display them individually.

Practical use of *args

One common use of *args is in functions that need to perform operations on a list of elements of unknown size. For example, a function that calculates the average of several numbers:
python
Here, the average function can calculate the result regardless of the number of values passed.

Limitations and considerations

Although *args is very effective, it is important to use it judiciously. Functions that use *args can become difficult to understand if they are not well documented. Therefore, it is essential to provide clear comments and docstrings explaining the role of each argument.

Tips for debugging

When using *args, it is helpful to add assertions or type checks to ensure that the received arguments are in the expected format. This can prevent hard-to-diagnose errors later in development.
In summary, the *args variable is an indispensable tool for creating flexible and versatile Python functions, provided it is used thoughtfully and documented.

Using the kwargs variable in function definitions

The **kwargs variable in Python is a great tool for managing an indefinite number of named arguments in functions. It allows capturing these arguments in the form of a dictionary, which offers great flexibility for manipulating them.

Definition and syntax of **kwargs

When a function is defined with **kwargs, all additional named arguments passed to the function are grouped into a dictionary. Each key of the dictionary corresponds to the name of an argument, and each value corresponds to the value of that argument.
Code example:
python
In this example, display_profile can receive any number of named arguments and display them. Each key-value pair is processed individually, providing great flexibility.

Practical applications of **kwargs

One of the most common uses of **kwargs is in functions that need to handle configurations or optional parameters. This allows for creating clear and customizable function interfaces.
Application example:
python
In this example, configure_system allows modifying default parameters through **kwargs, illustrating how to integrate configurable options.

Considerations for **kwargs

Although **kwargs is powerful, it is crucial to clearly document each option that the function can accept. This helps avoid misunderstandings and ensures that users of your function know exactly how to use it.
Additionally, it is often helpful to combine **kwargs with default values or validations to handle incorrect or unexpected inputs.
Ultimately, **kwargs is an essential tool for Python developers looking to design flexible and intuitive functions that can adapt to various needs without sacrificing code clarity.

Argument order in a function

When defining functions in Python, the order of arguments is crucial to ensure that the function behaves as intended and is intuitive to use. An incorrect order can lead to errors or confusion about how to correctly call the function.

Argument order rule

In Python, the order of arguments in a function definition should generally follow this sequence:
  1. Mandatory positional arguments.
  2. Optional positional arguments (with default values).
  3. *args to capture additional positional arguments.
  4. Mandatory named arguments.
  5. Optional named arguments (with default values).
  6. **kwargs to capture additional named arguments.
Example of function definition:
python
In this example, arg1 and arg2 are mandatory positional arguments, opt_arg is an optional positional argument with a default value, *args captures additional positional arguments, name_arg is a mandatory named argument, name_opt_arg is an optional named argument with a default value, and **kwargs captures additional named arguments.

Best practices

Following this order makes it easier for other developers to understand the function and reduces the risk of errors when calling it. Here are some additional best practices:
  • Clarity and documentation: Document each argument in a docstring to indicate its role, expected types, and the expected effects of its use.
  • Minimal use of kwargs**: Use *argsand**kwargs` only when necessary to maintain the readability and clarity of the function.
  • Testing and validations: Include validations for received arguments, particularly for *args and **kwargs, to ensure they contain the expected types and values.
By following these principles, you can create robust and easy-to-maintain functions, ensuring high-quality Python code.

Unpacking with asterisk operators: * and **

Unpacking with the asterisk operators * and ** is a powerful feature in Python that allows for easy passing of collections of arguments to functions. These operators also facilitate iterating over collections and merging dictionaries.

Using the * operator

The * operator is used to unpack sequences such as lists or tuples when passing them as arguments to a function. This allows for breaking down the elements of the sequence into individual arguments.
Example of unpacking a list:
python
In this example, the list numbers is unpacked, and its elements are passed as individual arguments to the add function.

Using the ** operator

The ** operator is used to unpack dictionaries when passing their key-value pairs as named arguments to a function. This is particularly useful for managing configurations or options.
Example of unpacking a dictionary:
python
In this example, the dictionary info is unpacked, and its values are passed as named arguments to the display_info function.

Best practices

Using unpacking operators can make code more readable and modular, but it is essential to ensure that the sequences or dictionaries contain appropriate elements to avoid errors.
  • Pre-checking: Ensure that the collection to be unpacked matches the expected parameters of the function.
  • Error handling: Prepare your code to handle potential exceptions when the data structure does not meet expectations.
By understanding and effectively applying unpacking, you can simplify the management of data collections in your Python functions.

Conclusion

Using variadic arguments in Python, via the operators *args and **kwargs, as well as their unpacking with * and **, provides considerable flexibility in creating functions. By mastering these tools, you can design functions that are not only robust but also adaptable to a variety of scenarios, which is essential for developing efficient and maintainable Python code.

Key takeaways

  • Increased flexibility: Using *args and **kwargs allows for creating functions that can handle an indefinite number of arguments, making your code more generic and reusable.
  • Clean argument management: By respecting the order of arguments (positional, *args, named, **kwargs), you can avoid common errors and ensure that your function receives the necessary parameters in the correct format.
  • Effective unpacking: The operators * and ** simplify the passing of arguments by unpacking collections, which is particularly useful for working with lists, tuples, and dictionaries.

Practical application tips

  • Documentation: Good documentation of functions using these techniques is crucial. It helps not only to understand the role of each argument but also to ensure that users of your code can use it correctly.
  • Unit testing: Writing unit tests for functions using *args and **kwargs can be very helpful in ensuring that all argument combinations work as expected and that your code remains reliable even with future changes.
  • Readability: While these features offer great power, it is important to keep an eye on readability. Too much abstraction can make the code hard to follow for other developers.
By integrating these practices into your projects, you can significantly improve the quality and flexibility of your Python applications. Not only will you gain efficiency, but you will also contribute to creating cleaner and more maintainable code, which is essential for long-term development.

Want to go further?

This topic is part of our Become a Data Analyst course. Browse the full programme, or get it by email.

Share with

Photo de Romain DE LA SOUCHÈRE

Romain DE LA SOUCHÈRE

Tech Lead, CTO AXI Technologies

Expert Data Engineering et Cloud, Romain affiche plus de 11 ans d'expérience, dont plusieurs années comme Lead Developer sur des solutions Smart Building haute performance. Il y a conçu et mis en production des moteurs de traitement capables d'absorber des centaines de milliers de données de capteurs par minute, ainsi que des bases clusterisées gérant plus de 10 millions de données dynamiques. Certifié Microsoft Azure DevOps Engineer Expert, il maîtrise aussi bien le développement back-end (Python, C#) que le DevOps (Docker, Kubernetes, Terraform) et les agents LLM. Formateur en Python, cloud, DevOps et IA générative appliquée, il forme avec une obsession : Amener chaque apprenant à concevoir et déployer des architectures réellement scalables en production.

» Learn More

Associated trainings

All our trainings
Image de la formation Become a Data Analyst
Become a Data Analyst
6 months
Intermediate
Guarantee