Что нового в Python 3.11

Изменения в Python 3.11 включают:

  • оптимизацию производительности с добавлением изменений, связанных с ускорением и inline-развёртыванием вызова функций, применением быстрых интерпретаторов типовых операций (x+x, x*x, x-x, a[i], a[i] = z, f(arg) C(arg), o.method(), o.attr = z, *seq), а также оптимизацией в рамках проектов Cinder и HotPy. Разработчики обещают прирост скорости выполнения кода на 10-60%. В среднем производительность при прохождении тестового набора pyperformance увеличилась на 25%;
  • переработанный механизм кэширования байткода, что позволило сократить время запуска интерпретатора на 10-15%. Объекты с кодом и байткод статически размещаются интерпретатором, чтобы исключить стадии демаршалинга извлечённого из кэша байткода и преобразования объектов с кодом для размещения в динамической памяти;
  • вывод информации о выражении при отображении трассировки вызовов в диагностических сообщениях. Расширенную информацию о трассировке также можно получить через API и использовать для сопоставления отдельных инструкций байткода с конкретной позицией в исходном коде, используя метод codeobject.co_positions() или функцию C API PyCode_Addr2Location(). Это упрощает отладку проблем, связанных с вложенными объектами словарей, множественными вызовами функций и сложными арифметическими выражениями;
  • поддержку групп исключений, дающих программе возможность генерировать и обрабатывать сразу несколько разных исключений одновременно. Для группировки нескольких исключений и их совместного вызова предложены новые типы ExceptionGroup и BaseExceptionGroup, а для выделения отдельных исключений из группы добавлено выражение “except*”;
  • добавление метода add_note() в класс BaseException для прикрепления текстового примечания к исключению;
  • добавление типа Self, представляющего текущий закрытый класс, для аннотирования методов, возвращающих экземпляр своего класса, более простым путём;
  • добавление специального типа LiteralString, который может включать только строковые литералы, совместимые с типом LiteralString. Тип можно использовать для ограничения передачи функциям строковых аргументов, где произвольная подстановка частей строк может привести к уязвимостям;
  • добавление TypeVarTuple, охватывающего произвольное число типов;
  • включение модуля tomllib с функциями для разбора формата TOML в стандартную библиотеку;
  • возможность пометки отдельных элементов типизованных словарей (TypedDict) метками Required и NotRequired для определения обязательных и необязательных полей;
  • добавление класса TaskGroup в модуль asyncio с реализацией асинхронного контекстного менеджера, ожидающего завершения группы задач. Добавление задач в группу осуществляется при помощи метода create_task();
  • добавление декоратора классов, методов и функций @dataclass_transform, при указании которого система проверки статических типов трактует объект, как при использовании декоратора @dataclasses.dataclass;
  • добавление возможности использования атомарной группировки ((?>…)) и possessive-квантификаторов (*+, ++, ?+, {m,n}+) в регулярных выражениях;
  • добавление опции командной строки “-P” и переменной окружения PYTHONSAFEPATH для отключения автоматического прикрепления к sys.path потенциально небезопасных файловых путей;
  • улучшение утилиты py.exe для платформы Windows, в которой реализована поддержка синтаксиса “-V:<company>/<tag>” в дополнение к “-<major>.<minor>”;
  • преобразование многих макросов в C API в обычные или статические inline-функции;
  • удаление модулей uu, cgi, pipes, crypt, aifc, chunk, msilib, telnetlib, audioop, nis, sndhdr, imghdr, nntplib, spwd, xdrlib, cgitb, mailcap, ossaudiodev и sunau. Удаление функции PyUnicode_Encode*.

@python_job_interview – практика на Python в нашем канале.

Началось альфа-тестирование ветки Python 3.12. Она будет находиться на стадии альфа-выпусков в течение семи месяцев. Затем ещё три месяца будет проводиться тестирование бета-версий с исправлением ошибок. 

Разберем подробно самые интересные улучшения

PEP 657: локатор трассировки ошибок

Раньше, до Python 3.11, при вызове исключения в трассировке ошибок содержалась лишь строка с описанием ошибки. Например:

x, y, z = 1, 2, 0
a, b, c = 3, 4, 5
result = (x / y / z) * (a / b / c)

В этом коде выдается ошибка, потому что при делении X/Y на Z получается 0.

Что нового в Python 3.11

Это сообщение об ошибке неинформативно: неизвестно, какой частью кода ошибка вызвана.

В Python 3.11 вы увидите:

Что нового в Python 3.11

С локатором ошибок ~~^~~ выясняется первопричина: Y или Z равен нулю. В коде посложнее эти аннотированные трассировки мощнее.

PEP 673: тип self

Подсказки типа. Чтобы сослаться на сам текущий класс, раньше приходилось явно определять переменную типа:

Что нового в Python 3.11

В версии 3.11 на сам инкапсулирующий класс ссылается тип Self и определять переменную типа не нужно:

Что нового в Python 3.11

Доработан асинхронный менеджер контекста {asyncio}

При асинхронном программировании код выполняется поэтапно. Чтобы не ждать завершения этапа до перехода к следующему, в Python используется модуль {asyncio}.

Создаем асинхронные задачи, ждем запуска каждой и собираем их с помощью asyncio.gather():

## Задачи: [start_time, duration]errandsDict = {
'Grocery Shopping': [11, 2],
'Return Packages': [9, 1],
'Pick Up Kids': [6, 1],
}

async def errands_log(task, start_time, time_to_finish):
await asyncio.sleep(start_time)
print(f"({task}) starting at {start_time}am")

await asyncio.sleep(time_to_finish)
print(f"({task}) done at {start_time+time_to_finish}am\n ======;")

## Асинхронные задачи
async def run_errands():
errands = []
for errand, (start_time, time_to_finish) in errandsDict.items():
errands.append(errands_log(errand, start_time, time_to_finish))

## Сбор всей информации после запуска
await asyncio.gather(*errands)

asyncio.run(run_errands())

При запуске в терминале получаем:

Что нового в Python 3.11

Но отслеживать список задач вручную и затем собирать их с asyncio.gather затруднительно. В Python 3.11 появилась новая функция/класс TaskGroup():

## With asyncio.TaskGroup
async def run_errands():
async with asyncio.TaskGroup() as tg:
for errand, (start_time, time_to_finish) in errandsDict.items():
tg.create_task(errands_log(errand,
start_time,
time_to_finish))

Она используется как контекстный менеджер, в котором содержится группа задач, и они все ожидаются им по завершении. Синтаксис здесь проще.

PEP 654: группа исключений

В версии 3.11 добавлена группа исключений  —  аналог функции «группировки» для их обработки. Это несколько исключений, обернутых в одно.

Когда ошибка приводит к вызову ExceptionGroup, вызываются оба обернутых исключения, отображаемые в собственной области группы исключений:

Что нового в Python 3.11

Для обработки ошибок, обернутых в ExceptionGroup, в Python 3.11 добавлено ключевое слово except*:

Что нового в Python 3.11

Эта функция эффективнее в {asyncio} со множеством запускаемых вместе асинхронных задач.

PEP 678: настраиваемые примечания об исключениях

Другая новая функция для обработки ошибок  —  примечания об исключениях с добавлением (при помощи add_note) настраиваемых сообщений:

Что нового в Python 3.11

PEP 659: увеличенная скорость выполнения

Благодаря инициативе Faster CPython Python 3.11 ожидается на 10–60% быстрее прошлых версий.

Усовершенствования стандартных библиотек

Есть несколько других улучшений качества стандартных библиотек. Прежде всего, в модуль math добавлены две долгожданные функции.Есть несколько других улучшений качества жизни стандартных библиотек. Прежде всего, в математический модуль добавлены две долгожданные функции.
>>> import math
>>> math.cbrt(9)  # Find the cube-root of x
2.080083823051904
>>> math.cbrt(27)
3.0000000000000004
>>> math.exp2(5)  # Raise 2 to the power of x
32.0

Тот факт, что Python потребовалось 28 лет, чтобы добавить функцию кубического корня, довольно удивителен, но, как говорится, лучше поздно, чем никогда.

В модуль дробей также добавлена ​​новая функция, позволяющая создавать дроби из строк:

>>> from fractions import Fraction
>>> Fraction("22/7")  # New in Python 3.11
Fraction(22, 7)
>>> Fraction(numerator=22, denominator=7)
Fraction(22, 7)
>>> Fraction("3e-4")
Fraction(3, 10000)
>>> Fraction("-73/41")
Fraction(-73, 41)
>>> Fraction(3.1415)  # Find the closest approximation to the given float
Fraction(7074029114692207, 2251799813685248)

В итоге: переходить на Python 3.11 или нет?

Не обновляйте эксплуатационную среду, если у используемых в ваших проектах библиотек нет совместимости с Python 3.11.

Проверить это рекомендую в Google colab. Чтобы перейти на Python 3.11, запустите:

!sudo apt-get update -y
!sudo apt-get install python3.11
!sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 1
!sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 2

Мы рассмотрели самые интересные новые функции, все улучшения и изменения смотрите в официальной документации к выпуску.

Источник

Источник2

+1
0
+1
0
+1
0
+1
0
+1
0

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *