python 3.8

Awesome New Python 3.8 Features

A number of new Python features have been added to the version 3.8. Some of the features are simply awesome.

This article will outline some of the new features of Python 3.8 which I reckon we should be familiar with.

1. Assignment Expressions :=

  • It is also known as walrus operator.
  • It assigns values to variables as part of an expression without the need to initialise the variables up front.

Let’s understand it with an example. Consider this code snippet:

if (my_variable := get_input()) is not None:
 print(my_variable) #exists now

In the code above, my_variable did not exist before the first line was executed. The walrus operator := was used to declare and initialise the variable “my_variable”. The return of the function “get_input()” is then used to assign a value to the variable. As a result, we can now print the value of the my_variable variable.

This feature is available in list comprehensions and statement forms.

There are some important points to note. Firstly, ensure the assignment of the variable is parenthesized. Unparenthesized assignment expressions are prohibited at the top level of an expression statement:

my_variable := get_input() #Invalid
(my_variable := get_input()) #Valid but it is not recommended

Secondly, = and := are not the same, and the priority around the commas is different.

Review this code below:

my_variable = a, b, c # Sets my_variable to (a, b, c)
(my_variable := a, b, c)  # Sets my_variable to a

There is a great deal of information available in the Python documents around walrus operator.

2. Positional-only parameters (/)

If you want to call a function in Python that accepts parameters then you can pass the arguments by position or by keyword.

But what if we want to restrict the callers of our API to only call our function by passing in parameters by position? What if our parameter names do not make sense to the external world (for what ever reason) OR we might be planning to rename the parameters in the future AND we want to make our API backwards compatible?

The positional-only parameter functionality “/” solves it.

Let’s understand it with an example:

def add(a, b, c, d=None, /):
    x = a+b+c
    if d is not None:
        x = x+d
    return x

The function “add” accepts three mandatory parameters: a,b and c, and an optional parameter d. The last parameter “/” indicates that the parameters of the function must be specified positionally. As a result, we cannot call the function by passing in parameters by keyword.

  • Subsequently, add(1,2,3) and add(1,2,3,4) are valid calls.
  • add(a=1,b=2,c=3) or add(1,2,3,d=4) are all invalid calls.

The result of the “/” parameter indicates that the function accepts positional-only parameters and thus the arguments must be mapped to the parameters based solely on their order.

There are few uses of this operator. Firstly, the parameter names of a function might not be meaningful to the external callers. The API authors can then restrict the callers from passing in the parameter name to set the values. With positional-only functions, API writers can rename the parameters of a function (if required) without breaking the code of the API callers. Hence, it encourages the API to be backwards compatible.

However in my view, it might be difficult to get used to this functionality initially as it can encourage inconsistent behaviour of function calling in the API.

3. For Debugging Ease, f-strings now support =

This is an improvement to the f-strings. The specifier “=” can be added to the f-strings now.

f -strings are in the form of f'{expr=}' Notice the ‘=’. The equal sign essentially evaluates the expression and prints the result too.

Let’s understand this with an example.

Imagine there are two variables “input ”and “output”, and we want to print “input-output” along with the result. We can use the f-strings=

input = 100
output = 50

This would now print input-output=50.

As a result, it could make the code neater as we do not need to copy the formula on the right hand side of the “=” to evaluate it, and the side effect is that it can be used extensively during debugging.

4. New date and datetime constructors are added for “fromisocalendar”

New date and datetime constructors have been added to return the ISO calendar object:

  1. date.fromisocalendar(yearweekday)

This is the inverse of the function: date.isocalendar(). Essentially, it takes in the year, week and day and returns the corresponding ISO calendar date object.

  1. datetime.fromisocalendar(yearweekday)

This is the inverse of the function: datetime.isocalendar(). Essentially, it takes in the year, week and day and returns the corresponding ISO calendar date-time object.

Add your comment