Опубликовано Оставить комментарий

Новые возможности в Python 3.9

Python 3.9 в настоящее время находится на четвертой стадии бета-тестирования (по состоянию на июль 2020 года). Хотя некоторые вещи могут измениться, но теперь совершенно ясно, как будет выглядеть новая версия.

Дженерики встроенных типов в аннотациях

Начиная с версии 3.9 появилась возможность использовать привычные для нас built-in коллекции в качестве аннотаций с указанием типа содержимого этих коллекций. Напомню, что ранее для таких целей использовались объекты ListDict из модуля typing. Вот как это теперь выглядит:

def do_stuff(data: list[int]):
    pass

Вот некоторые коллекции, которые теперь можно обобщить:

  • tuple
  • list
  • dict
  • set
  • frozenset
  • typecollections.deque
  • collections.abc.Coroutine
  • re.Pattern
  • и многое другое

Объединение словарей

До Python 3.9 стандартными способами слияния с dicts были:
1. Метод .update: a.update (b)
2. {** a, ** b}
Теперь появится еще один. | Оператор объединения делает именно то, что должен: Aunion of 2 dicts:

a = {'cars': 5, 'phones': 2}
b = {'cows': 10, 'lizards': 3}
a | b
// {'cars': 5, 'phones': 2, 'cows': 10, 'lizards': 3}

Как и .update или {** a, ** b}, это может привести к потере данных, если в файле dict есть дубликаты ключей. Кроме того, этот оператор одинаково хорошо работает с расширенным назначением:

a = {'cars': 5, 'phones': 2}
b = {'cows': 10, 'lizards': 3}
a |= b
print(a)
// {'cars': 5, 'phones': 2, 'cows': 10, 'lizards': 3}

Удаление суффиксов и префиксов

Новые методы .removesuffix() и .removeprefix() для str делают это:

'SubaruImpreza`.removeprefix('Subaru') // 'Impreza' 
'SubaruImpreza'.removesuffix('Impreza') // 'Subaru'

Новый парсер

В Python 3.9 используется новый парсер. Он основан на PEG (грамматика синтаксического анализа выражения), в отличие от старой, которая использует LL (синтаксический анализатор слева направо). Это было сделано потому, что возможности синтаксического анализатора LL были исчерпаны, и стало все труднее реализовывать новые языковые функции. Скорее всего, вы не заметите никакой разницы — производительность сопоставима, а полная обратная совместимость подтверждена.
Вы должны заботиться об этом, только если ваш код использует модуль синтаксического анализа из стандартной библиотеки. Некоторое время назад она устарела и не будет работать с новым парсером. В качестве обходного пути вы можете переключиться обратно на старый анализатор, используя аргумент -X oldparser или переменную окружения PYTHONOLDPARSER = 1.

Модуль zoneinfo

В Python 3.9 появился новый модуль под названием zoneinfo. Он реализует класс ZoneInfo, который обеспечивает поддержку часовых поясов IANA.

from zoneinfo import ZoneInfo
from datetime import datetime, timedelta
timestamp = datetime(2020, 7, 15, 11, tzinfo=ZoneInfo("America/Los_Angeles"))

Модуль Graphlib

Еще один новый модуль — на этот раз для работы с графами. Прямо сейчас он реализует только алгоритм топологической сортировки для направленных ациклических графов. Если вы не поняли, что я только что написал, вам, скорее всего, не потребуется новый модуль. Для тех из вас, кто знаком с теорией графов, вот как должен использоваться модуль (взято из документации по Python):

>>> graph = {"D": {"B", "C"}, "C": {"A"}, "B": {"A"}}
>>> ts = TopologicalSorter(graph)
>>> tuple(ts.static_order())
('A', 'C', 'B', 'D')

Обновления в math

В модуле math появилось несколько интересных апдейтов, а именно:

  • функция нахождение наибольшего общего делителя теперь может принимать неограниченное количество аргументов, ранее она принимала только 2 math.gcd(10, 15, 20, 100)
  • появилась функция нахождения наименьшего общего кратного, math.lcm