Python has long held key positions on the most popular programming languages list. It currently ranks first in the TIOBE Index for July 2022 & PYPL Popularity of Programming Language, ahead of Java, JS, and C/C++. This article will discuss the most important features that have appeared in recent years and why you should switch to them.

Changes in Python 3.8

Release Date: October 2019

Self-documenting expressions and debugging for f-strings

We will recall how with Python 3.6, users got an excellent opportunity to format strings using the .format() method and the f prefix before the line and {} to place data inside the expression. Often we needed to name what we were deriving to add specifics.

Example Before

Since version 3.8, users can create lines for self-documenting expressions and debug. It has become even easier to do this. We add the symbol `=` inside the {} and get the same result.

Example Now

New walrus `:=` operator

We can directly perform two actions in a condition, a loop, or something else: assign a value to a variable and then compare the expression. Let's give an example of a simple console application that displays everything the user enters, as long as the line is not empty.

Example Before

Here we assign the result of user input twice: before the loop and in its body. Now we have a way to immediately save the outcome of the execution when checking the condition:

Example Now

As you can see, we follow the same steps: first, we assign a value to the user_input variable, then perform the validation. If it worked, we go into the loop and output the updated content of user_input until the user input is empty.

How about using the user_input variable later in the code, after the loop? We will present a situation where we will create two variables using the walrus operator:

Example Now

Let's try to output the value outside the conditional statement:

Example Now

However, you should notice that Python will reject any and checks if the first operand is False. So, `n` will always be created, but `first_company` will only be made when the expression `n == 1` or the next `n > 1` is executed.

Example Now

As we can see, n also exists after the body of the conditional statement if, when first_company was not initialized, so we got the NameError: name 'first_company' is not defined.

This approach makes it possible to create more concise designs, but the main thing is not to mess around too much. :)

Ability to specify positional-only arguments

Here is an explanation from the official documentation:

Now users can limit parameters that must pass positionally and cannot be passed as a keyword, positional, positional or keyword, only keyword, to some functions.

Example Now

Let's give an example of built-in functions where we should not transfer keywords but only positional parameters.

Example Now

We cannot pass keywords 'a, b' arguments to the divmod function. Likewise with len(), where we pass only positional arguments:

Example Now

You will ask: how to transfer args/kwargs in this case? Here's how:

Example Now

DictReader returns a simple dict instead of an OrderedDict

With Python3.7, we got guaranteed ordered dicts, which covered all the possible advantages of collections.OrderedDict used to have over dict. So we got a logical change of return result in csv module. If previously DictReader necessarily returned a list of OrderedDicts:

Example Before

Now, since Python3.7, it no longer makes sense, so the result is currently not an OrderedDict, but a simple dict.

Example Now

Changes in Python 3.9

Release Date: October 2020

Ability to use | (ior) from dict

Using | for dict! Now we have the possibility to use | (ior) and with dict. Merging when using |, and updating when using |= as an assignment operator

Example Now

And

Example Now

Type hinting using built-in collections types

Now you don't need to import the typing module to add typing to lists, dicts, sets, and other built-in classes.

Example Now

.removeprefix() and .removesuffix() will override .startswith() or .endswith()

Are you using the .startswith() or .endswith() string methods to match and remove? Users now can do this more easily with the new .removeprefix() and .removesuffix() methods.

Example Now

Changes in Python 3.10

Release Date: October 2021

Using the new Union `|` operator

In Python 3.9, we looked at adding built-in collections to type hinting. In Python 3.10, we received another improvement - the use of the new Union operator `|`. If previously we were forced to specify all types in Union:

Example Before

Now we specify the types, breaking one with the other operator '|':

Example Now

The same applies to Optional because it is a Union[Type, None].

Example Before

Example Now

It may be noted that mypy supports PEP-604.

Ability to use context managers with parentheses

The change will help to split several collections that users pass to the context manager into several lines:

Example Now

Now it looks a lot nicer than single-line iterating across commas. Note that the trailing comma is supported.

Structural Pattern Matching

We will not discuss the historical component; let's just say that this feature came to us from many other languages, for example Haskell, Scala, Rust or many others. We need to immediately note that Pattern Matching should not be confused with a simple Match Case because it is not just a switch statement like in C++. Pattern matching here acts both as a verification mechanism and as data unpacking and manages the execution flow.

Syntax:

Example Now

It was often necessary to build structures like this one:

Example Before

Someone will say that it is possible to write it shorter, for example by separating the list of beginners into a list/tuple - OK:

Example Before

However, now we can do it more easily:

Example Now

As you can see, you can use | ("or"), and instead of "default", we use _ (wildcard). It will work if all other cases above do not work. Note that after this block, you cannot use other cases. Otherwise you will receive a SyntaxError: wildcard makes remaining patterns unreachable error.

Example Now

Will they write like that in the future? We will check in the coming years because the choice of old or new records ultimately depends on the users.

Did we say that's not all? 😀

There are also cases when users not only check for equality for some reason but want to check whether the input data is a list or a tuple. In this case, the annotation is not enough because it only helps static analysis with the help of linters, development environments or mypy, and anything can still get into the input of such a function. After successful validation, we want to extract and use the value in the body of the condition:

Example Before

This is how we did checking and unpacking in previous versions, but why leave it this way if Pattern Matching allows you to do two things at once:

Example Now

Elegant, isn't it? You can think of many use cases; one of them could be using Pattern Matching with classes. Let's give an example.

Let's describe the classes, Vector2D and Vector3D:

Example Now

Let's create a function that accepts an instance of the Vector2D or Vector3D class as a matcher and displays information about them otherwise we will display "Another vector":

Example Now

As you can see, the entries are very similar to calling Vector2D or Vector3D constructors, but you need to understand that the matcher does not call constructors. Verification takes place by comparing the parameters. We can even check exclusively for x=0 when creating such an instance would result in a TypeError:

Example Now

We will leave you the opportunity to experiment and find your ways of using this operator. However, we are sure that this operator will be frequently used due to its conciseness and multifunctionality, provided it is used correctly.

Key takeaways

Modern market dynamics require constantly updating knowledge and quickly responding to new trends. We are confident that new functionality will update the best-practice list soon, which means that you, as a specialist, will be able to speed up the development and maintenance of your code. Thank you for reading. Glory to Ukraine🇺🇦