Python *args and **kwargs

Python *args and **kwargs allow your functions to accept a variable number of arguments. *args is used to pass a non-keyworded, variable-length argument list to your function. At the same time, **kwargs allows you to pass keyworded, variable-length arguments to a function like a dictionary.
Table of Contents

Understanding Python *args and **kwargs

Python *args and **kwargs are special syntaxes that allow a function to accept a variable number of arguments. They are used when unsure how many arguments might be passed to your function. The *args syntax collects extra positional arguments into a tuple, while **kwargs collects extra keyword arguments into a dictionary. These features make functions much more flexible, as they can gracefully handle different numbers of arguments without needing to define each one explicitly. Python *args and **kwargs are especially useful when writing functions that must be generic and reusable in various contexts.

Syntax of Python *args and **kwargs

def my_function(*args, **kwargs):
  # Function body

Explanation

  • def my_function(: Defines a function named my_function.
  • *args: Collects all extra positional arguments into a tuple named args.
  • **kwargs: Collects all extra keyword arguments into a dictionary named kwargs.
  • # Function body: The code that the function will execute.

Example of Python *args and **kwargs

def example_function(*args, **kwargs):
    print("args:", args)
    print("kwargs:", kwargs)

example_function(1, 2, 3, a=4, b=5)

Explanation

  • def example_function(*args, **kwargs):: Defines a function named example_function that accepts any number of positional and keyword arguments.
  • print("args:", args): Prints the tuple args.
  • print("kwargs:", kwargs): Prints the dictionary kwargs.
  • example_function(1, 2, 3, a=4, b=5): Calls the function with three positional arguments and two keyword arguments.

Output

args: (1, 2, 3)
kwargs: {‘a’: 4, ‘b’: 5}


Function without Python *args and **kwargs

A function defined without *args and **kwargs in Python has a fixed number of parameters. When calling such a function, you must provide arguments that exactly match the parameters in the function definition, both in number and type (positional or keyword). If you provide too few or too many arguments, or if you use keyword arguments for parameters that aren’t defined to accept them, Python will raise a TypeError. This kind of function definition is less flexible but can be more straightforward when the number and type of inputs are known and fixed.

Syntax

def my_function(arg1, arg2, kwarg1=default_value, kwarg2=default_value):
  # Function body

Explanation

  • def my_function(: Defines a function named my_function.
  • arg1, arg2: Required positional arguments.
  • kwarg1=default_value, kwarg2=default_value: Optional keyword arguments with default values.
  • # Function body: Code that the function will execute.

Example

def fixed_function(a, b, c=3):
    print("a:", a)
    print("b:", b)
    print("c:", c)

fixed_function(1, 2)

Explanation

  • def fixed_function(a, b, c=3):: Defines fixed_function with two required arguments (a, b) and one optional argument c with a default value of 3.
  • print("a:", a): Prints the value of a.
  • print("b:", b): Prints the value of b.
  • print("c:", c): Prints the value of c.
  • fixed_function(1, 2): Calls fixed_function with values for a and b. c will take its default value.

Output

a: 1
b: 2
c: 3


Python *args

Python *args is used in a function definition to allow the function to accept any number of positional arguments. These arguments are collected into a tuple named args within the function. It is a way to pass a variable-length list of arguments to your function. Inside the function, you can iterate over the args tuple to access each argument passed.

Syntax

def my_function(*args):
  # Function body

Explanation

  • def my_function(: Defines a function named my_function.
  • *args: Syntax allows the function to accept any number of positional arguments, which are then packed into a tuple named args.
  • # Function body: This is where you write the code that will use the args tuple.

Example

def sum_all(*args):
    total = 0
    for number in args:
        total += number
    return total

result = sum_all(1, 2, 3, 4)
print(result)

Explanation

  • def sum_all(*args):: Defines a function sum_all that accepts any number of arguments and stores them in a tuple named args.
  • total = 0: Initializes a variable total to 0.
  • for number in args:: Loop iterates over each element in the args tuple.
  • total += number: Adds each number to the total.
  • return total: Returns the final sum.
  • result = sum_all(1, 2, 3, 4): Calls sum_all with four arguments and stores the result in result.
  • print(result): Prints the result, which is the sum of the arguments.

Output

10


When to use *args?

You should use *args when you want to create a function that can handle an arbitrary number of positional arguments. This is particularly useful when you don’t know how many arguments will be passed to the function. A typical example is when you’re writing a function that operates on a set of values, like summing them up, where the number of values can vary.

Syntax

def my_function(*args):
  # Code that uses the args tuple

Explanation

  • def my_function(: Defines a function named my_function.
  • *args: Allows my_function to accept any number of positional arguments. The * unpacks the arguments into the tuple args.
  • # Code that uses the args tuple: Where you write the code to process the arguments.

Example

def print_arguments(*args):
    for arg in args:
        print(arg)

print_arguments('apple', 'banana', 'cherry')

Explanation

  • def print_arguments(*args):: Defines a function print_arguments that accepts any number of arguments.
  • for arg in args:: Loop iterates through each argument in the args tuple.
  • print(arg): Prints the current argument.
  • print_arguments('apple', 'banana', 'cherry'): Calls print_arguments with three string arguments.

Output

apple
banana
cherry


Python **kwargs

Python **kwargs is used in a function definition to allow the function to accept any number of keyword arguments. These arguments are collected into a dictionary named kwargs within the function. Each key in the kwargs dictionary corresponds to the keyword used when calling the function; the value is associated with that keyword. It’s like having a flexible set of named parameters that your function can accept.

Syntax

def my_function(**kwargs):
  # Function body

Explanation

  • def my_function(: Defines a function named my_function.
  • **kwargs: Syntax allows the function to accept any number of keyword arguments, which are then packed into a dictionary named kwargs.
  • # Function body: Where you write the code that will use the kwargs dictionary.

Example

def describe_person(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

describe_person(name="Alice", age=30, city="New York")

Explanation

  • def describe_person(**kwargs):: Defines a function describe_person that accepts any number of keyword arguments.
  • for key, value in kwargs.items():: Loop iterates over the key-value pairs in the kwargs dictionary.
  • print(f"{key}: {value}"): Prints each key-value pair.
  • describe_person(name="Alice", age=30, city="New York"): Calls describe_person with three keyword arguments.

Output

name: Alice
age: 30
city: New York


When to use **kwargs?

You should use **kwargs when you want to create a function that can handle an arbitrary number of keyword arguments. This is particularly useful when you’re not sure in advance what named parameters might be passed to your function. Using **kwargs makes your function more adaptable, as it can accept and process additional named parameters without changing the function’s definition. A common use case is when you’re creating functions that set or modify options or settings, where the number and names of the options can vary.

Syntax

def my_function(**kwargs):
  # Code that uses the kwargs dictionary

Explanation

  • def my_function(: Defines a function named my_function.
  • **kwargs: Allows my_function to accept any number of keyword arguments. The ** unpacks the arguments into the dictionary kwargs.
  • # Code that uses the kwargs dictionary: Where you write the code to process the keyword arguments.

Example

def set_attributes(**kwargs):
    attributes = {}
    for key, value in kwargs.items():
        attributes[key] = value
    print(attributes)

set_attributes(color="red", size="large", material="wood")

Explanation

  • def set_attributes(**kwargs):: Defines a function set_attributes that accepts any number of keyword arguments.
  • attributes = {}: Initializes an empty dictionary called attributes.
  • for key, value in kwargs.items():: Loop iterates through the kwargs dictionary.
  • attributes[key] = value: Adds each key-value pair from kwargs to the attributes dictionary.
  • print(attributes): Prints the attributes dictionary.
  • set_attributes(color="red", size="large", material="wood"): Calls set_attributes with three keyword arguments.

Output

{‘color’: ‘red’, ‘size’: ‘large’, ‘material’: ‘wood’}


Ordering Arguments

When defining a function in Python, you should follow a specific order for different types of arguments. First, you list the standard positional arguments. Then comes the *args, which collects any extra positional arguments. After that, you can define any keyword-only arguments, and finally, you can use **kwargs to collect any remaining keyword arguments. Following this order ensures that Python can correctly match the arguments passed to the function with the parameters in the function definition.

Syntax

def my_function(pos_arg1, pos_arg2, *args, kw_only_arg1, kw_only_arg2, **kwargs):
  # Function body

Explanation

  • def my_function(: Defines a function named my_function.
  • pos_arg1, pos_arg2: Standard positional arguments.
  • *args: Collects any extra positional arguments into a tuple.
  • kw_only_arg1, kw_only_arg2: Keyword-only arguments. They must be specified by name when calling the function.
  • **kwargs: Collects any remaining keyword arguments into a dictionary.
  • # Function body: Where you write the code that the function will execute.

Example

def example_function(a, b, *args, c=None, d=None, **kwargs):
    print("a:", a)
    print("b:", b)
    print("args:", args)
    print("c:", c)
    print("d:", d)
    print("kwargs:", kwargs)

example_function(1, 2, 3, 4, 5, c=6, d=7, e=8, f=9)

Explanation

  • def example_function(a, b, *args, c=None, d=None, **kwargs):: Defines example_function with two positional arguments (a, b), *args, two keyword-only arguments (c, d), and **kwargs.
  • print("a:", a): Prints the value of a.
  • print("b:", b): Prints the value of b.
  • print("args:", args): Prints the args tuple.
  • print("c:", c): Prints the value of c.
  • print("d:", d): Prints the value of d.
  • print("kwargs:", kwargs): Prints the kwargs dictionary.
  • example_function(1, 2, 3, 4, 5, c=6, d=7, e=8, f=9): Calls the function with various arguments.

Output

a: 1
b: 2
args: (3, 4, 5)
c: 6
d: 7
kwargs: {‘e’: 8, ‘f’: 9}


Python *args and **kwargs to Call a Function

You can use both *args and **kwargs to call a function in Python, which is especially useful when you want to pass arguments from one function to another. The *args syntax unpacks a sequence (like a tuple or list) into positional arguments, while **kwargs unpacks a dictionary into keyword arguments. This technique allows a function to accept arguments flexibly and then pass them along to another function, even if the second function has a different signature.

Syntax

def another_function(arg1, arg2, kwarg1=None, kwarg2=None):
  # Function body

def my_function(*args, **kwargs):
  another_function(*args, **kwargs)

Explanation

  • def another_function(: Defines a function named another_function which will be called using my_function.
  • arg1, arg2: Positional arguments for another_function.
  • kwarg1=None, kwarg2=None: Keyword arguments with default values for another_function.
  • def my_function(*args, **kwargs):: Defines my_function that accepts any number of positional and keyword arguments.
  • another_function(*args, **kwargs): Calls another_function, unpacking args into positional arguments and kwargs into keyword arguments.

Example

def another_function(a, b, c=None, d=None):
    print("a:", a)
    print("b:", b)
    print("c:", c)
    print("d:", d)

def caller_function(*args, **kwargs):
    another_function(*args, **kwargs)

caller_function(1, 2, d=4)

Explanation

  • def another_function(a, b, c=None, d=None):: Defines another_function which accepts two positional arguments and two keyword arguments.
  • print("a:", a): Prints the value of a.
  • print("b:", b): Prints the value of b.
  • print("c:", c): Prints the value of c.
  • print("d:", d): Prints the value of d.
  • def caller_function(*args, **kwargs):: Defines caller_function which accepts any number of positional and keyword arguments.
  • caller_function(1, 2, d=4): Calls caller_function with positional arguments 1, 2 and a keyword argument d=4.

Output

a: 1
b: 2
c: None
d: 4


Python *args and **kwargs to Set Values of Object

You can use both *args and **kwargs in a class’s __init__ method to set attributes of an object dynamically. The *args can initialize attributes with positional arguments, while **kwargs allows setting attributes using keyword arguments. This gives you much flexibility when creating objects, as you don’t have to define each attribute explicitly in the constructor. It’s handy when the attributes of an object vary depending on how it’s used.

Syntax

class MyClass:
  def __init__(self, *args, **kwargs):
    # Initialize attributes using args and kwargs

Explanation

  • class MyClass:: Defines a class named MyClass.
  • def __init__(self, *args, **kwargs):: Constructor for MyClass. It accepts any number of positional (*args) and keyword (**kwargs) arguments.
  • # Initialize attributes using args and kwargs: Where you write the code to set the object’s attributes based on the provided arguments.

Example

class MyClass:
    def __init__(self, *args, **kwargs):
        self.args = args
        for key, value in kwargs.items():
            setattr(self, key, value)

my_object = MyClass(1, 2, 3, a=4, b=5)
print(my_object.args)
print(my_object.a)
print(my_object.b)

Explanation

  • class MyClass:: Defines a class named MyClass.
  • def __init__(self, *args, **kwargs):: Constructor, accepting any number of positional and keyword arguments.
  • self.args = args: Assigns the positional arguments to an attribute named args.
  • for key, value in kwargs.items():: Loop iterates through the keyword arguments.
  • setattr(self, key, value): Sets an attribute on the object with the name key and the value value.
  • my_object = MyClass(1, 2, 3, a=4, b=5): Creates an object of MyClass with some arguments.
  • print(my_object.args): Prints the args attribute.
  • print(my_object.a): Prints the a attribute.
  • print(my_object.b): Prints the b attribute.

Output

(1, 2, 3)
4
5


Packing and Unpacking Using Both *args and **kwargs in Python

Packing and unpacking are powerful features in Python that are often used in conjunction with *args and **kwargs. Packing involves collecting multiple values into a single variable (e.g., a tuple for positional arguments with *args and a dictionary for keyword arguments with **kwargs). Unpacking is the reverse: taking a sequence or a dictionary and spreading its elements as individual arguments to a function call. This allows for dynamic and flexible function definitions and calls and elegant ways to handle data structures.

Syntax

# Packing
def my_function(*args, **kwargs):
  # args is a tuple, kwargs is a dictionary

# Unpacking
my_function(*my_list, **my_dictionary)

Explanation

  • # Packing: Comment indicates that the following code demonstrates packing.
  • def my_function(*args, **kwargs):: Defines a function that packs extra arguments into args (tuple) and kwargs (dictionary).
  • # args is a tuple, kwargs is a dictionary: Comment explains the data types of args and kwargs.
  • # Unpacking: Comment indicates that the following code demonstrates unpacking.
  • my_function(*my_list, **my_dictionary): Calls my_function, unpacking my_list into positional arguments and my_dictionary into keyword arguments.

Example

def my_function(a, b, c, d=4, e=5):
    print(a, b, c, d, e)

my_list = [1, 2, 3]
my_dict = {'d': 40, 'e': 50}
my_function(*my_list, **my_dict)

Explanation

  • def my_function(a, b, c, d=4, e=5):: Defines a function my_function with three positional arguments and two keyword arguments with default values.
  • print(a, b, c, d, e): Prints the values of the arguments.
  • my_list = [1, 2, 3]: Creates a list my_list.
  • my_dict = {'d': 40, 'e': 50}: Creates a dictionary my_dict.
  • my_function(*my_list, **my_dict): Calls my_function, unpacking my_list into positional arguments a, b, c, and my_dict into keyword arguments d, e.

Output

1 2 3 40 50


Things to Remember

There are a few key things to remember when using *args and **kwargs in Python. First, *args must come before **kwargs in a function definition. Second, the names “args” and “kwargs” are just conventions; you could technically use any valid variable names preceded by * or **, but it’s best practice to stick with “args” and “kwargs” for clarity. Third, remember that *args collects extra positional arguments into a tuple, while **kwargs collects extra keyword arguments into a dictionary. Finally, using *args and **kwargs can make your code more flexible but also make it less readable if overused, so use them judiciously.


Conclusion

Python *args and **kwargs are powerful features that add flexibility to your functions by allowing them to accept various arguments. *args handles any positional arguments, packing them into a tuple, while **kwargs handles any number of keyword arguments, packing them into a dictionary. Understanding how to use these features, the proper ordering of arguments, and the principles of packing and unpacking are essential for writing reusable Python code. They are especially useful in function forwarding, subclassing, and creating functions that operate on various inputs or options. While they offer great flexibility, using them thoughtfully is important to maintain code readability and avoid potential confusion.


Python Reference

Defining Functions

Keyword Arguments

Table of Contents