What's that *args stuff in Python?
4 min read
We've all called functions or methods of a class and then we see our editor show stuffs like so:
The focus is on
*values part of the picture.
Most times, we just use the thing and go our way.
In this post, we'll see the purpose of that asterisk stuff (usually called
*args) and how to use it to eliminate boredom and reduce tension in our Python functions and methods.
Y'all remember Isaac? Well, he's got a problem here.
Isaac has been employed by Genghis Khan, one of the greatest men the world will ever see, to automate the process of ending the lives of his enemies.
This is Isaac's second serious job and he is ready to impress the Emperor of the Mongol Empire, so he creates an
dispatch_foe function that accepts a list of names of people and then reduce pollution by doing what is necessary.
He churns a function like so:
from GenghisKhan.actions import kill def dispatch_foe(name: str) -> bool: success: bool = kill(name) # ends the life return success
Calling this function on lots of people involves doing something like so:
for name in list_of_names: dispatch_foe(name)
This could be quite laborious for the soldiers involved and only does the dirty work for them. It does not really automate lots.
A small solution
Well, Isaac then decides to make his function accept a list of the names and then do the rest:
from typing import List from GenghisKhan.actions import kill def dispatch_foe(names: List) -> bool: success: bool = True for name in names: success = success and kill(name) # tells us if and only if everyone died return success
and we can call
dispatch_foe like so:
# people who we both share mutual hate enemies = ["Erons", "Victor Aiyeola", "Davidemi"] # test to confirm that they were successfully dispatched assert True is dispatch_foe(enemies)
An actual solution (The why)
While Isaac's solution works, it is stupid. Why? Simply because if we accept it, I'll never be able to teach you what
*args does. That means you'll wallow in complete ignorance till the end of your life span.
This has a dangerous effect. In the event the life of someone can only be saved by
*args, our refusal to reject Isaac's answer will spell the end of that person who may be a key soul to solving world hunger and therefore lead to millions and billions of deaths. This is why we always have to reject Isaac's first solution to solving any problem.
Most times, you'd want your function to accept a variable number of arguments without specifying a default.
*args is a beautiful and pythonic way to do that.
So we'd use it instead of lists or tuples or dictionaries (ah, there's a trick to this one, I'll write an article on it someday) or sets or arrays or vectors or linked lists or doubly linked lists or triply linked lists or quadruply linked lists or ...
An actual solution (The real stuff, without ment attached)
So, we'll rework Isaac's solution so soldiers can pass as many enemies as possible without having to pack them into a list:
from typing import Sequence from GenghisKhan.actions import kill def dispatch_foe(*names: Sequence[str]) -> bool: success: bool = True for name in names: success = success and kill(name) # tells us if and only if everyone died return success
and we can call our function in different ways like so:
# 'do' Erons alone assert True is dispatch_foe("Erons") # 'do' Erons and someone else assert True is dispatch_foe("Erons", "Someone else") # 'do' people who hate me assert True is dispatch_foe("Erons", "Davidemi", "Victor Aiyeola")
And there, little mortal one, is an elegant solution to Isaac's problem. Genghis khan did use Isaac's solution for solving the problem of enemies. Unfortunately, Isaac's name isn't in the history books. Yeah because some organizations and some successful products don't give their engineers enough praise.
It's important to know that the '*' character was introduced by PEP448 and is usually referred to as iterable unpacking operator.
Know also, that the usage of
**kwargs (we'll learn this later) can make debugging quite evil. So you'd want to watch your back whilst using them.
There is no
GenghisKhan module implemented anywhere in the Python standard library or Pypi index or anywhere. No murders were committed in the course of this code and my enemies are excellent engineers with happy jobs (I don't have one, so I don't like them at all).
Also, there is no proof that Genghis Khan actually asked Isaac to write this function. I must have written this article while dreaming.
The actual end
May the force of the snaky language dwell richly in your soul and may you find what is that good, pleasing and perfect will of The One Above All.