Asterisk (*) and forward slash (/) as function parameters in python

Written by: Chirag (Srce Cde)



asterist and forward slash as function parameters python

In Python, the asterisk (*) and forward slash (/) symbols are used in function signature/definition to denote flexible argument passing mechanisms. These symbols enable functions to accept a varying number of arguments by position or as keyword arguments. Understanding how to use these symbols can significantly enhance the flexibility and readability of your Python code.

Asterisk (*variable_name) for variable positional function parameters

The asterisk (*) symbol in the function signature followed by a variable name is used to collect additional positional arguments in the function call as a tuple.

def asterisk_arg_func(first_argument, *additional_args):
    print(f"First argument : {first_argument}")
    print(f"Additional arguments : {additional_args}")

*additional_args allows to pass any number of arguments beyond explicitly defined arguments (i.e. first_argument). *additional_args retains the order/position of the passed arguments; hence called as positional arguments.

# Function invocation
asterisk_arg_func(1, 2,'three',4.0)

# Output
'''
First argument : 1
Additional arguments : (2, 'three', 4.0)
'''

In the above example 1 is assigned to first_argument and 2, 'three', 4.0 (a tuple) is assigned to additional_args.


Asterisk (*) to unpack arguments

The asterisk (*) can also be used in function invocation to unpack iterables into positional arguments.

def addition(x, y, z):
    return x + y + z

numbers = [1, 2, 3]
print(f"Sum of {numbers} is  ::: {addition(*numbers)}")

# Output
# Sum of [1, 2, 3] is  ::: 6

Here, *numbers unpacks the list into individual arguments, which are then passed to addition function. The number of arguments in the function definition and the length of unpacked iterables should be same, else it will throw an exception.


** for variable keyword arguments

Double asterisks (**) are used in function definition to collect additional keyword arguments as a dictionary. This is useful for accepting arbitrary keyword arguments in a function.

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

print(my_function(name="Srce Cde", gender='M'))

# Output
'''
name: Srce Cde
gender: M
'''

my_function function accepts any number of keyword arguments and processes them as a dictionary.


Stand alone * to specify Keyword-Only Parameters

* is used in function signature to indicate that parameters defined after * are keyword-only. This means that they can only be specified by keyword and not by position.

def my_function(a, b, *, c, d):
    print(a, b, c, d)

my_function(1, 2, c=3, d=4) # Valid
my_function(a=1, b=2, c=3, d=4) # Valid
my_function(1, 2, 3, 4) # TypeError

In the above example, a and b can be passed as positional or keyword-based argument but c and d can only be passed as keyword-based argument. If you try to pass c and d by position then it will raise TypeError exception. Any parameters that are defined after * should be passed as keyword-only arguments.


/ to specify Position-Only Parameters

In python 3.8, use of the slash (/) symbol was introduced in function signature to indicate that parameters defined before it (/) are position-only. This means they can only be specified by position and not by keyword.

def my_function(a, b, /, c, d):
    print(a, b, c, d)

my_function(1, 2, 3, d=4) # Valid
my_function(a=1, b=2, c=3, d=4) # TypeError

In the above example, a and b must be specified/passed by position, whereas c and d can be specified/passed by as position or keyword argument. If you try to pass a and b as keyword arguments then it will throw a TypeError exception. Any parameters that are defined before / should be passed as position-only arguments.


* and \ both in function signature

You can combine * and / in a single function definition/signature to define position-only parameters, keyword-only parameters, and variable positional parameters.

def my_function(a, /, b, *, c):
    print(a, b, c)

my_function(1, b=2, c=3) # Valid
my_function(1, 2, c=3) # Valid
my_function(a=1, b=2, c=3) # TypeError: my_function() got some positional-only arguments passed as keyword arguments: 'a'

In the above example, a is position only argument (since it is defined before /), b can be position or keyword based argument and c should be a keyword argument (since it is defined after *).


Conclusion

The use of * and / in Python function definitions provide a powerful way to create flexible and clear interfaces for functions. By understanding and utilizing these features, Python developers can write more adaptable and maintainable code that can handle a wide variety of input arguments.