engineering

4min read

What’s New in Python 3.8—A Summary of the New Features

Intro

The newest Python version—the Python 3.8—was released on October 14th, 2019. In this article, I will go briefly through the new features. For more detailed information, please check the official documentation.

Assignment expressions—Walrus Operator

The most significant change in the new Python was widely discussed and controversial in the Python community; however, this topic is beyond this article. What is this controversy about? It regards the assignment expressions denoted with := which is also known as “the walrus operator” due to its resemblance to the eyes and tusks of a walrus. Thanks to this new feature, you can save some lines of code by assigning value to a variable as part of an expression.

It can be helpful when you need to use len() function or match object twice:

if (n := len(a)) > 10:
    print(f"List is too long ({n} elements)")

if m := re.search("[abc]", "spam"):
    print(m.group())

This operator is also handy with while-loops and comprehensions:

while (command := input("> ")) != "quit":
    print("You entered:", command)

[
    clean_name.capitalize()
    for name in names
    if (clean_name := name.lower()) in allowed_names
]

It is recommended to limit the use of walrus operators only to clean cases that reduce complexity and improve readability. Details with complimentary examples are described in PEP 572, check it out.

Positional-only arguments

The new function parameter syntax /** indicates that some function parameters must be specified positionally and cannot be used as keyword arguments. **It may be useful when arguments have a natural order, but it is hard to name them well. Positional-only arguments help to preserve backward compatibility without having to worry that other dependent functions would rely on argument names. You can mix it with keyword-only arguments as well. Positional-only arguments are described in detail in PEP 570.

def name(
    positional_only_parameters,
    /,
    positional_or_keyword_parameters,
    *,
    keyword_only_parameters
):
    pass

Improved typing

The Python typing system has already been great, but it was improved further by adding more precise types. Now typing can be more narrow.

These types are:

  • Typed dictionaries
  • Literal types
  • Final objects
  • Protocols

Typed dictionaries

“Regular” type of Dict[K, V] is suitable for uniform dictionaries where each value has the same type. To support a common pattern where the type of a value depends on the value of the key the typing.TypedDict was introduced.

By default, every key is required to be present. Specify total=False, to allow keys to be optional.

from typing import TypedDict

class Cat(TypedDict, total=False):
    name: str
    birth_year: int

filemon: Cat = dict(name="Filemon", birth_year=1991)
filemon: Cat = dict(name="Bonifacy")

PEP 589

Literal types

Literal types indicate that a parameter or return value is constrained to one or more specific literal values.

from typing import Literal

def get_status(port: int) -> Literal['connected', 'disconnected']:
    connection = Connection(port)
    if check_connection(port):
        return 'connected'
    return 'disconnected'

PEP 586

Final objects

The typing.Final is used to restrict subclassing, overriding, or reassignment.

from typing import Final

ID: Final = 1

@final
class Base:
   ...


class LessImportantClass:
    @final
    def important_function(self) -> None:

PEP 591

Protocols

By using Protocols, it is possible to define which methods and attributes are required.

from typing import Protocols

class Named(Protocol):
    name: str

class SupportsClose(Protocol):
    def close(self) -> None:def say_hi(obj: Named) -> None:
    print(f"Hi {obj.name}")

def close_that_thing(thing: SupportsClose) -> None:
    thing.close()

PEP 544

f-string debugging

It is a common pattern to print the expression and its value. In the new Python, you can avoid redundant typing in the f-string by adding = specifier at the end of expression—the expression and its value will be returned.

>>> python = 3.7
>>> f"python={python}"
'python=3.7'

>>> python = 3.8
>>> f"{python=}"
'python=3.8'

Other features

Here are some other changes that are available in the new Python:

  • warnings about dangerous syntax,
  • improved math and statistics functions,
  • importlib.metadata module,
  • optimizations, performance improvements.

For the full list of the new features, check the official documentation.

Wrapping up

New Python brings interesting things to the table. They have been around for some time in beta-versions, so most of the bugs are eliminated. It is definitely worth checking this out. However, you have to be aware that some libraries may not support Python 3.8 yet. If you have a Python-based project in mind, don’t hesitate to contact us!

Tobiasz Kędzierski

Junior Software Engineer

Did you enjoy the read?

If you have any questions, don’t hesitate to ask!