How to Specify Positional-Only Parameters in Python

John John (304)
0

If you're familiar with Python's keyword-only arguments, then you've probably wondered why the same constraint doesn't exist for positional arguments. This changes with Python 3.8's introduction of positional-only parameters.

Keyword-only arguments

In case you're not familiar with keyword-only arguments, I'll give a quick overview. Any keyword argument defined after an * will be required as a named argument. See the following examples:

def my_function(arg1, arg2, *, kwarg1=False, kwarg2=True):
    pass

In the above function, both kwarg1 and kwarg2 will be required as keyword arguments. This means the user cannot call the function with all positional arguments. See what happens:

>>> my_function(1, 2, 3, 4)
---------------------------------------------------------------------------
TypeError: my_function() takes 2 positional arguments but 4 were given

Instead, we must use:

>>> my_function(1, 2, kwargs1=3, kwarg2=4)

Position-only parameters

We can also require that arguments be specified as positional-only, meaning they cannot be specified as keyword arguments.

The main reason for using either keyword-only or positional-only arguments is to improve readability. However, one advantage to using positional-only arguments is that it improves performance. The parsing and handling of positional arguments is faster than keyword arguments.

Posted in these interests:
h/python67 guides
h/code69 guides

If a slash / is included in the function definition, any arguments specified before the slash are positional-only. This is the opposite of keyword-only arguments, where everything after the asterisk are keyword-only.

If that's confusing hopefully the following will help:

def my_function(<positional-only>, /, <positional-or-keyword>, *, <keyword-only>):
    pass

Here's a real example of positional-only parameters:

def my_function(arg1, arg2, /, arg3, arg4):
    pass

So, arg1 and arg2 must be specified as positional arguments, but arg3 or arg4 can be either.

Both of the following work:

my_function(1, 2, 3, 4)
# or
my_function(1, 2, arg3=3, arg4=4)

but this will not:

>>> my_function(arg1=1, arg2=2, arg3=3, arg4=4)
---------------------------------------------------------------------------
TypeError: my_function() got some positional-only arguments passed as keyword arguments: 'arg1, arg2'
Python 3.8 Features
Assignment ExpressionsPycache Prefix
Show all in the Python 3.8 Features series
John John (304)
5 minutes

As a JavaScript developer, you'll often need to construct URLs and query string parameters. One sensible way to construct query string parameters is to use a one layer object with key value pairs.