Наступил 2020 год, а значит, Python 2 перестал поддерживаться. Если быть совсем точным, то основные разработчики уже перестали заниматься веткой, а выход релиза 2.7.18, приуроченный к PyCon US в апреле 2020 года, ознаменует полное прекращение любой активности, связанной с Python 2.
С другой стороны, совсем недавно состоялся релиз Python 3.8, добавивший немного синтаксического сахара в язык. Python 3.9 же ожидается ещё нескоро, да и пока не похоже что добавит в язык что-то интересное.
Так что если вы вдруг ещё не отказались от Python 2, то дальше тянуть смысла просто нет: поддержка второй версии уже прекратилась, а переход сразу на 3.8 позволит использовать язык в его самом актуальном состоянии ещё долгое время.
Ну а, чтобы решиться было проще, ниже приведён обзор главных нововведений Python 3.8, которые пригодятся каждому питонисту.
1. Выражения присваивания (Assignment expressions)
Так же известные как «моржовый оператор» (walrus operator) — новый синтаксис, который позволит присваивать значения переменным внутри другого выражения. Это, наверное, самое известное и обсуждаемое из нововведений версии 3.8.
a = 6
# Код ниже присваивает b значение a ** 2
# и проверяет, если b > 0
if (b := a ** 2) > 0:
print(f'Квадрат {a} это {b}.') # Квадрат 6 это 36.
Целью введения оператора является повышение читаемости кода, поэтому использовать его (как и все остальные операторы) стоит не при первой же возможности, а только тогда, когда это уместно.
# так делать НЕ НАДО
a = 5
d = [b := a+1, a := b-1, a := a*2]
2. Только позиционные аргументы
Функции могут принимать два типа аргументов.
- Позиционные — передаваемые по позиции
- Именованные — передаваемые по имени
В коде ниже, значения обоих аргументов a и b можно передать как по позиции, так и по имени.
def my_func(a, b=1):
return a+b
my_func(5,2) # Оба аргумента позиционные
my_func(a=5, b=2) # Оба аргумента именованные
В новой версии Питона можно явно ограничить, какие из параметров могут быть только позиционными или только именованными с помощью символов / и * в сигнатуре функции (последний, правда, появился ещё до Python 3.8).
В примере ниже, первые два параметра a и b только позиционные, c и d могут быть любыми, а последние два e и f должны быть именованными.
def my_func(a, b, /, c, d, *, e, f):
return a+b+c+d+e+f
my_func(1, 2, 3, 4, 5, 6) # ошибка: e, f должны быть именованными
my_func(a=1, b=2, 3, 4, e=5, f=6) # ошибка: a, b должны быть позиционными
my_func(1, 2, c=3, 4, e=5, f=6) # returns 21
my_unc(1, 2, c=3, d=4, e=5, f=6) # returns 21
Зачем же ограничивать гибкость типов аргументов? В некоторых случаях использование имени параметра вместо его позиции будет бесполезным и неуместным. Ограничение так же позволит избежать проблем, если вы планируете изменить имена позиционных аргументов в будущем.
3. f-строки 2.0
Сложно описать словами, насколько проще и элегантнее сделали форматирование f-строки, появившиеся ещё в Python 3.6.
Сложно поверить, но Python 3.8 удалось сделать их ещё удобнее. Добавив знак = после имени подставляемой переменной, вы сможете вывести её имя и её значение без дублирования имени.
pi = 3 # В военное время может быть и так
print(f'pi={pi}.') # так мы делали раньше
print(f'{pi=}') # а так можно делать теперь
Дебаг с помощью print станет ещё удобнее :)
4. Обратный порядок элементов словаря
Итерироваться по словарям теперь можно в обратном порядке с помощью reversed().
5. Получение метаданных из других модулей
Новый модуль importlib.metadata позволит получать метаданные (например, версию) из сторонних пакетов.
6. finally + continue
Раньше нельзя было использовать выражение continue внутри finally из-за сложности в реализации этой фичи. Теперь можно.
for i in range(2):
try:
print(i)
finally:
print('Тест.')
continue
print('Эту строку вы не увидите.')
# Python <= 3.7
>> SyntaxError: 'continue' not supported inside 'finally' clause
# Python 3.8
>> 0
Тест.
1
Тест.