Вышел новый релиз Python 3.11, который содержит несколько приятных новых функций и функций. В этом обзоре перечислены наиболее важные изменения, которые помогут вам обновить Python.
Новый релиз содержит улучшения в области исключений и обработки исключений в Python, новый модуль для обработки файлов TOML, улучшения для интерпретатора, новые типы и функции, а также объявляет устаревшими некоторые старые модули и API языка. Кроме того, тесты Python утверждают, что Python 3.11 на 10–60% быстрее, чем Python 3.10: вы можете увидеть результаты здесь.
Как установить и обновить
линукс
В Linux (в данном случае: Ubuntu) вы можете установить и обновить Python через локальный менеджер пакетов. Вы можете использовать deadsnakes PPA для установки самых последних версий Python.
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
После добавления репозитория вы можете установить Python 3.11 через apt:
sudo apt-get update
sudo apt-get install python3.11
macOS
В macOS я рекомендую использовать менеджер пакетов homebrew. Вы можете установить доморощенный через:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
После установки homebrew вы можете установить Python 3.11:
brew install [email protected]
Или, если вы уже установили более раннюю версию Python через homebrew (и обновили сам менеджер пакетов), обновите пакет Python до версии 3.11 с помощью этой команды:
brew upgrade python -v 3.11
Окна
В Windows у вас есть два способа обновить Python: через установщик Python или менеджер пакетов Chocolatey. Вы найдете установщик Python на официальной странице загрузки, и он проведет вас через весь процесс. Если вы хотите использовать менеджер пакетов Chocolatey, вы можете установить его через:
Set-ExecutionPolicy Bypass -Scope Process -Force; \
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
Затем вы можете использовать Chocolatey для установки Python 3.11 через командную строку:
choco install python -y --version 3.11
Или вы обновляете Python, если он уже установлен:
choco upgrade python -y --version 3.11
Группы исключений, кроме* и примечания
Теперь можно вызывать и обрабатывать несколько несвязанных исключений одновременно. Недавно введенный тип ExceptionGroup
может объединять несвязанные исключения:
exceptions = ExceptionGroup(
"all",
[
TypeError(1),
ExceptionGroup("ex", [TypeError(2), ValueError(3)]),
ExceptionGroup("os", [OSError(4)])
]
)
Эти пакеты дают красивые печатные иерархии:
import traceback traceback.print_exception(exceptions)
| ExceptionGroup: all (3 sub-exceptions) +-+---------------- 1 ---------------- | TypeError: 1 +---------------- 2 ---------------- | ExceptionGroup: ex (2 sub-exceptions) +-+---------------- 1 ---------------- | TypeError: 2 +---------------- 2 ---------------- | ValueError: 3 +------------------------------------ +---------------- 3 ---------------- | ExceptionGroup: os (1 sub-exception) +-+---------------- 1 ---------------- | OSError: 4 +------------------------------------
Вы можете использовать условия соответствия для этих групп исключений, создавать их подклассы, создавать собственные обработчики для обработки так называемых листовых исключений и многое другое.
Python 3.11 представляет новое (или расширенное) ключевое слово для упрощения работы с ExceptionsGroups: except*
. Символ * указывает, что можно обрабатывать несколько исключений:
try:
...
except* CustomError:
...
except* OSError as e:
...
except* (TypeError, ValueError) as e:
...
Описание PEP-0654 предоставляет дополнительную документацию для нового ключевого слова except*
, например, рекурсивное сопоставление, вызов исключений в блоке исключений* или цепочка.
Базовый класс исключений BaseException
также стал новым методом. Этот метод был добавлен, поскольку при перехвате и повторном возникновении исключений может быть добавлена дополнительная информация.
add_note(note)
Добавьте строку
note
в примечания к исключению, которые отображаются в стандартной трассировке после строки исключения.TypeError
возникает, еслиnote
не является строкой.
Добро пожаловать в новый модуль: tomllib
Tom’s Obvious Minimal Language (TOML) задуман как формат файла конфигурации, который является минимальным и легко читаемым. Синтаксис похож на INI-файлы, но он представляет собой фактический стандарт, в то время как INI имеет множество разновидностей. TOML поддерживает различные типы данных: String, Integer, Float, Boolean, Datetime, Array и Table. Поскольку он состоит из пар ключ-значение, его структура удобно анализируется в виде хэш-карты. Ниже приведен минимальный пример:
# this is a TOML config file example
title = "Config"
[general] name = "Database" created = 2022-11-26T08:30:00+02:00
[database]
[database.connection] server = "192.168.1.1" ports = [ 8000, 8001, 8002 ]
[database.auth] username = "root" password = "root"
Теперь Python 3.11 добавляет в стандартную библиотеку модуль для разбора файлов TOML под названием tomllib. К сожалению, на данный момент модуль поддерживает только синтаксический анализ файлов TOML, но не их запись. Предлагаются две альтернативы, если вам нужны возможности записи: пакет Tomli-W и пакет TOML Kit.
Однако, если вам просто нужно прочитать файл TOML, вы можете использовать новый модуль из стандартной библиотеки. Имейте в виду, что любой файл TOML должен быть открыт в двоичном режиме, чтобы tomllib
мог правильно обрабатывать кодировку UTF-8 во всех системах. В следующем примере показано, как вы могли бы проанализировать наш пример файла TOML из приведенного выше:
import tomllib
with open("config.toml", "rb") as f: config = tomllib.load(f)
server = config['database']['connection']['server'] for port in config['database']['connection']['ports']: print(f'{server}:{port}')
Вы можете найти дополнительные советы и рекомендации по работе с модулем tomllib
в статье RealPython, например, указав метод float для управления анализом и представлением чисел с плавающей запятой.
Улучшения интерпретатора
Python 3.11 догоняет возможности более современных компиляторов и теперь также будет указывать конкретное выражение, вызвавшее ошибку, а не просто указывать на строку:
Traceback (most recent call last):
File "distance.py", line 11, in <module>
print(manhattan_distance(p1, p2))
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "distance.py", line 6, in manhattan_distance
return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'x'
Кроме того, есть новый параметр командной строки -P
, который вместе с переменной среды с именем PYTHONSAFEPATH
отключает автоматическое добавление потенциально небезопасных путей к sys.path
. Это функция, которую можно интегрировать в среду непрерывной интеграции для обеспечения безопасности и переносимости.
-P
Не добавляйте потенциально небезопасный путь к
sys.path
:
python -m module
командная строка: не добавляйте текущий рабочий каталог.
python script.py
командная строка: не добавляйте каталог сценария. Если это символическая ссылка, разрешите символические ссылки.
Командные строки
python -c code
иpython
(REPL): не добавляйте пустую строку, которая означает текущий рабочий каталог.
См. также переменную окружения
PYTHONSAFEPATH
и параметры-E
и-I
(изолированные).
Дополнительные типы и особенности типов
В новой версии представлены новые функции набора текста. Они кратко показаны в следующих разделах.
Вариативные дженерики
В Python 3.5 уже появилось TypeVar
для дженериков, параметризованных одним типом. В Python 3.11 появился TypeVarTuple
, который позволяет параметризовать произвольное количество типов. Следующий пример взят из PEP-646 и показывает использование этой новой функции:
from typing import TypeVar, TypeVarTuple
DType = TypeVar('DType') Shape = TypeVarTuple('Shape')
class Array(Generic[DType, *Shape]):
def __abs__(self) -> Array[DType, *Shape]: ... def __add__(self, other: Array[DType, *Shape]) -> Array[DType, *Shape]: ...
from typing import NewType
Height = NewType('Height', int) Width = NewType('Width', int)
x: Array[float, Height, Width] = Array()
Пометка отдельных элементов TypedDict как обязательных или необязательных
Теперь отдельные элементы в TypedDict
могут быть отмечены, должны ли они присутствовать или нет. По умолчанию все поля по-прежнему обязательны для обратной совместимости. Однако есть также параметр total
, для которого можно установить значение False
: в этом случае все поля TypedDict
по умолчанию не обязательны.
class Movie(TypedDict): title: str year: NotRequired[int]
m1: Movie = {"title": "Black Panther", "year": 2018} # OK m2: Movie = {"title": "Star Wars"} # OK (year is not required) m3: Movie = {"year": 2022} # ERROR (missing required field title)
Собственный тип
PEP-673 вводит аннотацию Self
для методов, которые возвращают экземпляр своего класса. В следующем примере показан вариант использования альтернативного конструктора:
class MyInt:
@classmethod
def fromhex(cls, s: str) -> Self:
return cls(int(s, 16))
Произвольный литеральный строковый тип
Python 3.11 представляет новую аннотацию для дополнительной безопасности в отношении строк: LiteralString
. Эта аннотация позволяет функциям принимать произвольные типы литеральных строк, а также строки, созданные из других литеральных строк. Вы можете установить требования к конфиденциальным функциям, например тем, которые выполняют операторы SQL для защиты от атак путем внедрения кода SQL.
В соответствии с PEP-675 показано, как эту аннотацию можно использовать для SQL-запросов:
def run_query(sql: LiteralString) -> ... ...
def caller( arbitrary_string: str, query_string: LiteralString, table_name: LiteralString, ) -> None: run_query("SELECT * FROM students") # ok run_query(query_string) # ok run_query("SELECT * FROM " + table_name) # ok run_query(arbitrary_string) # type checker error run_query( # type checker error f"SELECT * FROM students WHERE name = {arbitrary_string}" )
Старое должно уйти: устаревание
Следующие устаревшие стандартные библиотечные модули объявлены устаревшими и будут удалены в Python 3.13:
aifc
chunk
msilib
pipes
telnetlib
audioop
crypt
nis
sndhdr
uu
cgi
imghdr
nntplib
spwd
xdrlib
cgitb
mailcap
ossaudiodev
sunau
Кроме того, модули asynchat
, asyncore
и smtpd
(которые уже объявлены устаревшими) были обновлены, чтобы отметить, что они будут удалены в Python 3.12. Кроме того, пакет lib2to3
и инструмент 2to3
теперь устарели и, возможно, не смогут анализировать Python 3.10 или новее. Недокументированные модули sre_compile
, sre_constants
и sre_parse
теперь также устарели.
API-интерфейсы кодировщика Py_UNICODE были удалены, потому что они уже устарели и больше не используются, поскольку есть лучшие и более эффективные альтернативы. Если вы все еще используете эти API, соответствующий PEP-624 предоставляет руководство по миграции.
Некоторые макросы были преобразованы в статические встроенные функции, чтобы избежать подводных камней макросов. Вы можете найти дополнительную информацию об этих макросах в соответствующем PEP-670.
Заключение
Новый выпуск Python 3.11 приносит много нового и хорошего: улучшенную производительность, больше возможностей для обработки исключений, новый модуль для разбора файлов TOML, улучшения интерпретатора, дополнительные типы, аннотации и функции типов, а также устаревшие и удаление некоторого старого языкового багажа.
Решите для себя, стоит ли обновляться, но самое главное: продолжайте кодить и продолжайте творить!