The world’s leading publication for data science, AI, and ML professionals.

*args, **kwargs & How To Specify Arguments Correctly

Are you specifying your Python function arguments correctly?

Arguments in Python can be specified in four different ways.

They can be specified as:

  • Positional arguments
  • Keyword arguments
  • Arbitrary argument lists
  • Arbitrary keyword argument dictionaries

Here’s how to use them correctly.

Positional arguments

Positional arguments are, obviously, arguments that are specified by their position.

They are mandatory and have no default values.

Specifying arguments as positional arguments is the most commonly used and most simple way to set a function’s arguments.

It’s best to use these with simple functions that have a clear natural order, such as below:

def calculate_distance(start, end):
     distance = end - start
     return(distance)

If you then call this function without including the positional arguments, you will receive an error.

Of course, this is because you have required two positional arguments in your function but have not provided any when calling it.

Technically you can reverse the order of positional arguments by using the argument names. Technically you could write this:

def calculate_distance(end = 10, start = 5:
     distance = end - start
     return(distance)

And it would work. But this is verbose, pointless and just a bit stupid. So, don’t do this.

Keyword arguments

When a function has more than a couple of required arguments – it’s better to use keyword arguments. Keyword arguments also require defaults – which can be very useful. You can use these to specify optional keywords like the example below.

def calculate_distance(start, end, units = km):
     distance = end - start
     return(str(distance) + units)

For example, if we still wanted to calculate the distance travelled we might also want to include the unit of measurement. We might often work in kilometres but occasionally work in other metrics. Therefore, we can specify "km" as the default keyword argument, which can be replaced if needed. Therefore,

calculate_distance(5,10)
#returns '5km'
calculate_distance(5,10, units = "m")
#returns '5m'

We can, as above, just specify the arguments in order. We can also specify the arguments in different orders as long as we reference them. These are both bad practices, however. We should call the function in the same way we specify it. Which in this case would be:

calculate_distance(5,10, units = "m")

A final note on keyword arguments is that it is harder to remove an optional argument that was added than to add it in the future. So use keyword arguments only when you deem them essential.

Arbitrary argument lists

You can add an extensible number of positional arguments with the *args construct. Within the function, args will be a tuple of all the remaining positional arguments.

def example(name, birthday, *args):
    print(name)
    print(birthday)
    print(args)
    print(args[1])
    return
example("James", "september 4th", "something else", "another thing")

Therefore, if you define and call the function above with the arguments shown, you’ll get the following output.

As stated, ‘args’ is a tuple of all the other positional arguments required. You can extract from this tuple by positional indexing. Here, we specified two positional arguments, therefore args[1] is equal to the second thing in the tuple due to Pythons zero indexing.

However, if all the arguments that you pass in are of the same nature – it’s better to practice and simpler to pass in a list.

Arbitrary keyword argument dictionary

In the same way that positional arguments are related to keyword arguments, *args has a counterpart in *kwargs. It does effectively the same thing as args but instead of being positional arguments, they are named arguments. Therefore, if we run the function below:

def testing_function_two(name, birthday, **kwargs):
    print(name)
    print(birthday)
    print(kwargs)
    print(kwargs['kwarg2'])
return
testing_function_two("James", "september 4th", kwarg1 = "something else", kwarg2 = "another thing")

We get the output below:

As can be seen, **kwargs is a dictionary of all the passed named arguments that have not been caught by other keyword arguments.

Similarly to its counterpart, *args, it should be used sparingly and only when necessary.

Summary

If you can, stick to positional and keyword arguments. Use keyword arguments when there is no natural order. *args and **kwargs are great tools to have – but use them sparingly and only when needed.

Other programmers will appreciate simplicity more than anything so don’t use *args and **kwargs when they are verbose.

Happy arguing.

Thanks for reading and I hope this helps you.

If I've inspired you to join medium I would be really grateful if you did it through this link - it will help to support me to write better content in the future.If you want to learn more about Data science, become a certified data scientist, or land a job in data science, then checkout 365 data science through my affiliate link.

Here’s some other stuff I wrote:

Econometrics Is The Original Data Science

How to easily show your Matplotlib plots and Pandas dataframes dynamically on your website.

How to Easily Run Python Scripts on Website Inputs


Related Articles