Бета-цикл Python 3.8 уже запущен в лице Python 3.8.0b1, который был выпущен 4 июня, за которой вышла следующая бета 4 июля. Это значит, что Python 3.8 уже можно назвать завершенным делом, мы можем с уверенностью начать изучать особенности последнего реализа. Выпуск анонсирован на октябрь, так что пользователям не нужно долго ждать.
Оператор морж (walrus) в Python 3.8
Заглавная особенность Python 3.8, и в то же время — самая спорная. Путь принятия решения о PEP 572 («Assignment Expressions») был довольно ухабистым, что привело к новой модели управления языком.
Представим, что новое правительство готовится заменить давнего доброжелательного диктатора, которого мы с вами знаем всю жизнь, Гвидо ван Россума, после того как он уйдет в отставку из-за беспорядков, связанных с PEP 572 (конфликт между сообществом разработчиков из за добавления нового синтаксиса).
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
В связи с этим выходит новый оператор, который часто называют “оператор-морж” из-за ассоциации с его отображением. Использование :=
в if
или while
позволяет присвоить значение переменной во время тестирования. Предполагается, что это упростит такие задачи как сопоставление с несколькими шаблонами, так называемые “полтора цикла”, итак:
Было:
1 2 3 4 5 6 7 8 9 10 |
m = re.match(p1, line) if m: return m.group(1) else: m = re.match(p2, line) if m: return m.group(2) else: m = re.match(p3, line) ... |
Стало:
1 2 3 4 5 6 |
if m := re.match(p1, line): return m.group(1) elif m := re.match(p2, line): return m.group(2) elif m := re.match(p3, line): ... |
И цикл над неповторяемым объектом, например:
1 2 3 4 |
ent = obj.next_entry() while ent: ... # process ent ent = obj.next_entry() |
Может стать:
1 2 |
while ent := obj.next_entry(): ... # process ent |
Эти и другие примеры использования помогают прояснить намерения программиста. Подобная функция есть во многих других языках, но Python, конечно же, жил без этого почти 30 лет до данного момента. В общем и целом, трудно сказать почему такое небольшое изменение вызвало такой шум.
Поддержка отладки для f-strings в Python 3.8
f-strings (форматируемые строки) были добавлены в Python 3.6 и являются весьма полезными, однако пользователи довольно часто используют их для отладки вывода. Так что Эрик В. Смит предложил ввести дополнительный синтаксис для f-strings, чтобы упростить отладку вывода. Изначально идея пошла от Ларри Хастингса и синтаксис потерпел ряд изменений, это задокументировано в двух случаях feature-request на bugs.python.org #issue36774 и #issue36817. Итоговый результат мы можем рассмотреть с вами.
Вместо того, чтобы иметь дело с чем-то громоздким:
1 |
print(f'foo={foo} bar={bar}') |
Программисты на Python 3.8 смогут работать так:
1 |
print(f'{foo=} {bar=}') |
В обоих случаях, выдача будет следующей:
1 2 3 4 |
foo = 42 bar = 'answer ...' print(f'{foo=} {bar=}') # foo=42 bar=answer ... |
Кроме этого, некоторые модификаторы могут использоваться для изменения выдачи, !s
использует представление str()
, вместо значения по умолчанию epr()
, а !f
сможет иметь доступ к элементам управления форматированием. Их можно будет использовать следующим образом, используя в примере модуль math для работы с математическими функциями:
1 2 3 4 5 6 7 8 9 |
import datetime import math now = datetime.datetime.now() print(f'{now=} {now=!s}') # Результат: # now = datetime.datetime(2019, 7, 29, 10, 49, 0, 170211) now=2019-07-29 10:49:00.170211 print(f'{math.pi=!f:.2f}') # math.pi=3.14 |
Еще одна полезная функция, скорее косметическая это сохранение пробелов в выражении f-strings:
1 2 3 4 |
a = 37 print(f'{a = }, {a = }') # a = 37, a = 37 |
В конечном счете, пользователи смогут красиво выводить свои отладки, логирование и другие сообщения. Для кого-то это может показаться немного тривиальными изменениями, но на самом деле из этого можно извлечь много пользы. Мы знаем, что f-строки полностью заменили остальные механизмы интерполяции для большинства программистов Python.
Позиционные параметры в Python 3.8
Еще одно изменение в Python 3.8 предоставляет чистым функциям Python все те же опции для параметров, что уже реализованы в С. PEP 570 («Python Positional-Only Parameters») вносит новый синтасксис, который может быть использован в определениях функции для обозначения только позиционных аргументов — параметров, которые не могут быть переданы в качестве аргументов ключевых слов.
Например, встроенная функция pow()
должна вызываться с соответствующими аргументами:
1 2 3 4 5 |
pow(2, 3) # 8 pow(x=2, y=3) ... TypeError: pow() takes no keyword arguments |
Но если бы pow()
была чистой-функцией Python, чего и ожидала бы альтернативная реализация Python, было бы трудно изменить это поведение. Функция может принимать только *args
и **kwargs
, затем ставить условие, что kwargs
является пустым, однако потом скрывает, что собирается сделать функция. Есть и другие причины, описанные в РЕР, но с большей частью из них Python-программисты не то чтобы часто сталкиваются.
Однако те, кто сталкиваются, возможно обрадуются тому факту, что они могут написать функцию pow()
на чистом Python, которая будет вести себя так же, как и встроенная. Вот так:
1 2 3 4 5 |
def pow(x, y, z=None, /): r = x**y if z is not None: r %= z return r |
Наш /
обозначает конец позиционных параметров в списке аргументов. Суть такая же, как и для *
, который может быть использован в списке аргументов для делимитации ключевых аргументов (те, которые могут быть переданы как keyword=...
), что указано в РЕР 3102 («Keyword-Only Arguments»).
Итак, следующий пример:
1 2 |
def fun(a, b, /, c, d, *, e, f): ... |
Говорит нам, что а
и b
должны быть переданы позиционально, с
и d
могут быть переданы как позиционально, так и как ключевое слово, наши е
и f
должны быть переданы по ключевому слову. Итак:
КОД # легально
КОД # легально
КОД # нелегально
1 2 3 |
fun(1, 2, 3, 4, e=5, f=6) # правильно fun(1, 2, 3, d=4, e=5, f=6) # правильно fun(a=1, b=2, c=3, d=4, e=5, f=6) # неправильно |
Похоже, что большая часть Python-программистов не сталкивалась как с *
, так и с /
.
Подвижный __pycache__ в Python 3.8
Директория __pycache__
создана интерпретатором Python 3 (начиная с версии 3.2) для хранения файлов .pyc
. Эти файлы содержат байт код, который кешируется после того, как интерпретатор компилирует файлы .py
. Ранние версии Python просто выкидывали файлы .pyc
, но РЕР 3147 («PYC Repository Directories») изменило это.
Намерением была поддержка множественных установленных версий Python, наряду с вероятностью того, что многие из них могут не быть CPython вообще (например PyPy). Так что, например, стандартные файлы библиотеки могут быть скомилированы и кэшированы каждой версией Python так, как нужно.
Каждый может записать файл типа name.interp-version.pyc
в __pycache__
. Так что, например на системе Fedora, foo.py
будет скомилирован при первом использовании, и будет создан __pycache__/foo.cpython-37.pyc
С точки зрения производительности — это отлично, но может быть не так оптимально по другим причинам. Карл Мейер выполнил запрос функции, запрашивая у переменной среды сказать Python, где найти (и внести) эти файлы кэша. Он столкнулся с проблемами доступов в его системе и в конечном счете с отключением файлов кэша.
Итак, он добавил переменную среды PYTHONPYCACHEPREFIX
(также доступную через флаг командной строки -X pycache_prefix=PATH
) для указания интерпретатору о том, что место для хранения этих файлов будет другим.
Другие новинки в языке программирования Python 3.8
Python 3.8 получит более быстрое соглашение о вызовах для расширений С, основывайся на соглашении “fastcall”, которое используется внутри CPython. В Python 3.8 это представлено в экспериментальной манере (названия с префиксом подчеркивания), но ожидается, что конечный результат мы увидим в версии 3.9.
Обработку конфиуграций в интерпретаторе также почистили, так что язык может проще встраиваться в другие программы без необходимости в переменных среды и других механизмов конфигуарции, которые мешали бы работе установленной системы Python.
Также появились новые возможности в ряде стандартных модулях библиотеки. Например, модуль ast для обработки абстрактных древ синтаксиса Python получил новые возможности, такие как составление статисики и ввода.
Черновик документации “что нового в Python 3.8” имеет намного больше информации об упомянутых, и не упомянутых изменениях. Это очень подробное разъяснение того, что будет через несколько месяцев.
Статус PEP 594 («Removing dead batteries from the standard library») не до конца ясен, по крайней мере для нас. Идея удаления старых модулей стандартной библиотеки была на слуху довольно долго, PEP была запрошена в мае, и это довольно активно обсуждается с тех пор. Удаление надоевших модулей стандартных библиотек не вызывает много споров до тех пор, пока это не затронет ваш любимый модуль.
Руководящий совет не делал никаких заявлений о PEP, и не убрал старого Диктатора. Однако для PEP ясно, что даже если это будет принято, изменения в Python 3.8 будут минимальными. Некоторые модули могут начать вызывать ошибку PendingDeprecationWarning (многие уже это делают, так как считаются устаревшими какое-то время), однако главное изменение будет в документации. Все 30 (или около того) модулей будут задокументированы как модули с истекающим сроком годности, однако фактическое удаление не произойдет до релиза 3.10 — это около трех лет с настоящего момента.
Будущие релизы Python еще обсуждаются. На данный момент, Python 3.9 запланирован на июнь 2020, намного быстрее, чем обычно. Один цикл Python — это 18 месяцев, однако было предложено поменять его на 9 месяцев (или, например, год).
В любом случае, мы можем быть уверены в том, что Python 3.8 будет включать в себя упомянутые изменения (не говоря уже об не упомянутом) где-то в районе хеллоуина 31 октября.
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»