Wednesday 22 April 2015

Understand It Yourself Kit: *args and *kwargs for Python

This is a post aimed at Python programmers. Also, this will be useful for engineers who work in other languages like Java and are finding their way in Python.

Programmers are used to argument lists. For example, Java programmers are used to writing the main entry point of their program with an argument list. This looks like

Although other languages can have variable list of arguments in the form of maps and lists in all methods, this does not appear all over the languages for no particular reason. However, this is mainstream in Python code. So we will be seeing a lot of *args, and **kwargs as following in method definitions.

Programmers who come from other languages where this is not mainstream try to understand this from the caller environment whereas it is better the other way around. This kind of understanding also helps in designing flexible Python code. What that means is

If a method has formal arguments, *args and **kwargs, it is saying that, whatever you pass in addition to the formal arguments, will go into *args and any name value arguments will go into **kwargs. So you can call it with quite a lot of arguments in a number of ways. Close to anything goes.

For example the aFunction can be called as follows

But there are some rules to watch out for. For that here is a Understand It Yourself Kit, which you run and just read the output/code and figure it out yourself. A few base code for this was taken from 'Python Epiphanies from Stuart Williams'. This also has a lot of additions which bring up interesting parts of the rules.

Download and run the code from here.

How it is useful: Within the code, notice the call and how args and kwargs get assigned from the console. The extra arguments get assigned to args and kwargs.

Now have a look at the next call and its output. aFunction was called with name-value pairs packed into a dict (comes as kwargs). This got unpacked to its formal arguments.

Thats where this *args and **kwargs are useful. The additional parameters that are passed to aFunction even if they are not useful/make sense to aFunction, will get assigned properly to another function further up the call stack. aFunction just has to pass *args and **kwargs and if it makes sense to the next method, it will.

This is also useful when writing classes in Python. A child class constructor just passes the extra arguments to the parent's constructor call. An example is shown below

No comments: