The latest stable release of Python is out!

Open-source enthusiasts from all over the world have been working on new, enhanced, and deprecated features in Python for the past year.

Though the beta versions have been rolling out for quite some time, the official release of Python 3.9.0 happened on October 5, 2020.

#Python 3.9 is now officially available! Get it here:https://t.co/qVhXvbdhhh

Released on time, on budget, great features and optimizations, a million household uses! Easily our best release ever!

That is until 3.10 next year. But you go pester the new RM @pyblogsal for THAT! — Łukasz Langa (@llanga) October 5, 2020

The official documentation contains all the details of the latest features and changelog. Throughout this post, I’ll walk you through a few cool features that may come in handy in your day-to-day programming tasks.

We’ll check out the following:

  • Type hinting generics and flexible function and variable annotations
  • Union Operators in Dictionaries
  • **zoneinfo** — Accessing and calculating time zones
  • String methods to remove prefixes and suffixes
  • Other release highlights

To follow along with me or to try out the new features, you should have Python 3.9 installed.

I have used an environment manager called pyenv (alternatively, you can use conda) to get the latest version installed alongside my current version. You can also run it using the official docker image.

Flexible Function and Variable Annotations

Function annotations have been around since Python 3.0 and they enable us to add metadata to Python functions. So, what’s new in Python 3.9?

Python 3.9 added PEP 593. It introduced a mechanism to extend the type annotations fromPEP 484 which provides the standard semantic for annotations and suggested that annotations be used for type hinting.

Now, there can be many other use cases for annotations besides type hinting. So PEP 593 introduced typing.Annotated which allows you to add more details to the metadata.

Let’s try to understand this better via an example for both Python 3.8 and 3.9.

Python 3.8

def currency_exchange(eur: "euros", rate: "exchange rate") -> "euro to USD":
    """Converting Euros to USD using the exchange rate"""
    return eur * rate

This is a simple function that converts Euros to USD using the exchange rate. We have used the annotations to serve as documentation for the user.

Python 3.9

from typing import Annotated
def currency_exchange(eur: Annotated[float, "euros"], rate: Annotated[float, "exchange rate"]) -> Annotated[float, "euro to dollars"]:
    """Converting Euros to Dollars using the exchange rate"""
    return eur * rate

Here, we are using the newly introduced Annotated that takes at least two arguments. The first argument (float in the example) establishes the type hint, and the rest of the arguments are arbitrary metadata of the function.

The user/developer can also check these annotations using the __annotations__ attribute:

We can also check the type using the get_type_hint() function:

Type Hinting Generics in Standard Collections

Basic data types like int, str or bool are simple to annotate.

The earlier static typing was built incrementally on top of the existing Python runtime and constrained by it. This led to a duplicated collection hierarchy in the typing module due to the generics – that is, we had both typing.List and the built-in list.

With generics, we have the issue of parameterization due to their storage structure (which is a container). And for these reasons, we have not been able to use list(float) or list[float] as type hints directly. Instead, we needed a typing module to achieve this.

In Python 3.9, this duplicate hierarchy is no longer needed. We can annotate them directly:

scores: list(float)

How to Merge and Update Dictionaries

Two of the coolest and most useful features of Python 3.9 are the merge(|) and update(|=) operators added to the built-in dict class.

The existing (3.8) ways of merging two dicts have many shortcomings:

Python 3.8

  • Dict unpacking looks ugly and is not easily discoverable.
python = {2000: "2.0.1", 2008: "2.6.9", 2010: "2.7.18"}
python3 = {2008: "3.0.1", 2009: "3.1.5", 2016: "3.6.12", 2020: "3.9.0"}

##merging two dictionaries
{**python, **python3}

  • Another method is dict.update which modifies the original dictionary in-place:

Python 3.9

PEP 584 has introduced two new operators for dictionaries:

  • (|) union — to merge two dictionaries. It preserves the original dictionaries.
  • (|=) update — this is for in-place merging of dictionaries.
python = {2000: "2.0.1", 2008: "2.6.9", 2010: "2.7.18"}
python3 = {2008: "3.0.1", 2009: "3.1.5", 2016: "3.6.12", 2020: "3.9.0"}

##merging two dictionaries
python | python3

Preserved original dicts:

python |= python3
python

The update operator merges the dictionaries and updates the dictionary on the left of the operator while keeping the last values for the overlapping keys in the two dicts.

#python #programming #developer #web-development #machine-learning

Python 3.9 Updates Explained with Hands-on Code Examples
1.85 GEEK